mt_metadata.transfer_functions ============================== .. py:module:: mt_metadata.transfer_functions .. autoapi-nested-parse:: =============================== Transfer Functions Metadata =============================== This module provides a central container (TF) for magnetotelluric transfer functions, which represent the electromagnetic response of the Earth. Transfer functions relate the measured magnetic and electric fields and are fundamental to magnetotelluric interpretation. The primary goal is to create a unified transfer function object that can read from and write to various industry-standard file formats through the io module, enabling seamless data interchange and analysis across different MT software packages. MetadataBase Objects -------------------- * TF - Main transfer function container with impedance, tipper, and associated metadata * Station - Station-level metadata specific to transfer function processing * TransferFunction - Core transfer function metadata (impedance, tipper, processing info) * StatisticalEstimate - Statistical quality metrics and error estimates for transfer functions Supported File Formats (io module) ---------------------------------- The io module supports reading and writing the following transfer function formats: * **EDI** - SEG (Society of Exploration Geophysicists) EDI format, the most common MT interchange format * **EMTFXML** - EMTF (Electromagnetic Transfer Function) XML format with extended metadata support * **ZMM** - BIRRP processing output format (impedance and vertical field data) * **JFile** - EMTF/BIRRP .j format for transfer function coefficients * **ZongeMTAvg** - Zonge International averaged MT data format Channel Nomenclature -------------------- The module supports multiple channel naming conventions from different acquisition systems (default, LEMI, Phoenix, Musgraves, NIMS), with automatic mapping between standard channel names (hx, hy, hz, ex, ey) and system-specific labels. Usage ----- The TF object serves as a central repository that: - Stores transfer functions in an xarray.Dataset for efficient computation - Provides helper methods to access impedance, tipper, errors, and covariances - Reads/writes to multiple file formats transparently - Maintains full metadata provenance and processing history - Supports coordinate rotations and datum transformations Submodules ---------- .. toctree:: :maxdepth: 1 /source/api/mt_metadata/transfer_functions/core/index /source/api/mt_metadata/transfer_functions/io/index /source/api/mt_metadata/transfer_functions/tf/index Classes ------- .. autoapisummary:: mt_metadata.transfer_functions.TF Package Contents ---------------- .. py:class:: TF(fn = None, **kwargs) Generic container to hold information about an electromagnetic transfer funtion The thought here is to have a central container TF.dataset which is an xarray.Dataset that contains the impedance, tipper, errors and covariance values. There are helper functions to get and set these from the TF.dataset. Cause most of the time the user will want just the impedance or the tipper and associated errors. We are accommodating EMTF style covariances to accurately rotated data errors. When reading and writing edi files this information will be lost. .. py:property:: channel_nomenclature :type: dict Channel nomenclature dictionary keyed by channel names. For example: {'ex': 'ex', 'ey': 'ey', 'hx': 'hx', 'hy': 'hy', 'hz': 'hz'} .. py:attribute:: save_dir .. py:property:: fn :type: pathlib.Path reference to original data file .. py:property:: inverse_channel_nomenclature :type: dict[str, str] .. py:method:: copy() Create a deep copy of the current object. :returns: A deep copy of the current object. :rtype: Self .. py:property:: survey_metadata :type: mt_metadata.timeseries.Survey Survey metadata. .. py:property:: station_metadata :type: mt_metadata.transfer_functions.tf.Station Station metadata from survey_metadata.stations[0] .. py:property:: run_metadata :type: mt_metadata.timeseries.Run Run metadata from survey_metadata.stations[0].runs[0] .. py:property:: index_zxx :type: dict .. py:property:: index_zxy :type: dict .. py:property:: index_zyx :type: dict .. py:property:: index_zyy :type: dict .. py:property:: index_tzx :type: dict .. py:property:: index_tzy :type: dict .. py:property:: latitude :type: float Latitude .. py:property:: longitude :type: float Longitude .. py:property:: elevation :type: float Elevation .. py:property:: dataset :type: xarray.Dataset This will return an xarray dataset with proper metadata :returns: The xarray dataset with metadata. :rtype: xr.Dataset .. py:method:: has_transfer_function() Check to see if the transfer function is not 0 and has transfer function components :returns: True if the transfer function is not 0 and has components, False otherwise. :rtype: bool .. py:property:: transfer_function :type: xarray.DataArray | None returns: The transfer function data array or None if not set. :rtype: xr.DataArray | None .. py:property:: transfer_function_error :type: xarray.DataArray | None returns: The transfer function error data array or None if not set. :rtype: xr.DataArray | None .. py:property:: transfer_function_model_error :type: xarray.DataArray | None returns: The transfer function model error data array or None if not set. :rtype: xr.DataArray | None .. py:method:: has_impedance() Check to see if the transfer function is not 0 and has transfer function components :returns: True if the transfer function has impedance components, False otherwise. :rtype: bool .. py:property:: impedance :type: xarray.DataArray | None returns: The impedance data array or None if not set. :rtype: xr.DataArray | None .. py:property:: impedance_error :type: xarray.DataArray | None returns: The impedance error data array or None if not set. :rtype: xr.DataArray | None .. py:property:: impedance_model_error :type: xarray.DataArray | None returns: The impedance model error data array or None if not set. :rtype: xr.DataArray | None .. py:method:: has_tipper() Check to see if the transfer function is not 0 and has transfer function components :returns: True if the transfer function has tipper components, False otherwise. :rtype: bool .. py:property:: tipper :type: xarray.DataArray | None returns: The tipper data array or None if not set. :rtype: xr.DataArray | None .. py:property:: tipper_error :type: xarray.DataArray | None returns: The tipper error data array or None if not set. :rtype: xr.DataArray | None .. py:property:: tipper_model_error :type: xarray.DataArray | None returns: The tipper model error data array or None if not set. :rtype: xr.DataArray | None .. py:method:: has_inverse_signal_power() Check to see if the transfer function is not 0 and has transfer function components :returns: True if the inverse signal power is set and not zero, False otherwise. :rtype: bool .. py:property:: inverse_signal_power :type: xarray.DataArray | None Get the inverse signal power data array. :returns: The inverse signal power data array or None if not set. :rtype: xr.DataArray | None .. py:method:: has_residual_covariance() Check to see if the transfer function is not 0 and has transfer function components :returns: True if the residual covariance is set and not zero, False otherwise. :rtype: bool .. py:property:: residual_covariance :type: xarray.DataArray | None Get the residual covariance data array. :returns: The residual covariance data array or None if not set. :rtype: xr.DataArray | None .. py:property:: period :type: numpy.ndarray | None Periods of the transfer function .. py:property:: frequency :type: numpy.ndarray | None .. py:property:: station :type: str station name .. py:property:: survey :type: str Survey ID .. py:property:: tf_id :type: str transfer function id .. py:method:: to_ts_station_metadata() need a convinience function to translate to ts station metadata for MTH5 .. py:method:: from_ts_station_metadata(ts_station_metadata) need a convinience function to translate to ts station metadata for MTH5 .. py:method:: merge(other, period_min = None, period_max = None, inplace = False) metadata will be assumed to be from self. Merge transfer functions together. `other` can be another `TF` object or a tuple of `TF` objects to set bounds should be of the format [{"tf": tf_01, "period_min": .01, "period_max": 100}, {"tf": tf_02, "period_min": 100, "period_max": 1000}] or to just use whats in the transfer function [tf_01, tf_02, ...] The bounds are inclusive, so if you want to merge at say 1 s choose the best one and set the other to a value lower or higher depending on the periods for that transfer function, for example [{"tf": tf_01, "period_min": .01, "period_max": 100}, {"tf": tf_02, "period_min": 100.1, "period_max": 1000}] :param other: other transfer functions to merge with :type other: TF, list of dicts, list of TF objects, dict :param period_min: minimum period for the original TF :type period_min: float :param period_max: maximum period for the original TF :type period_max: float :param inplace: whether to modify the original TF or return a new one :type inplace: bool :returns: merged transfer function or None if inplace=True :rtype: TF | None .. py:method:: write(fn = None, save_dir = None, fn_basename = None, file_type = 'edi', **kwargs) Write an mt file, the supported file types are EDI and XML. .. todo:: j-files :param fn: Full path to file to save to. :type fn: str | Path | None :param save_dir: Full path save directory. :type save_dir: str | Path | None :param fn_basename: Name of file with or without extension. :type fn_basename: str | None :param file_type: Type of file to write. :type file_type: Literal["edi", "xml", "zmm", "avg", "j"] :param Optional Keyword Arguments: :param ---------------------------: :param longitude_format: whether to write longitude as longitude or LONG. options are 'longitude' or 'LONG', default 'longitude' :type longitude_format: str :param longitude_format: :type longitude_format: string :param latlon_format: degrees minutes seconds ('dms') or decimal degrees ('dd') :type latlon_format: format of latitude and longitude in output edi, :returns: * *str* -- Full path to the written file. * *Example: ::* -- >>> tf_obj.write(file_type='xml') .. py:method:: write_tf_file(**kwargs) .. py:method:: read_tf_file(**kwargs) .. py:method:: read(fn = None, file_type = None, get_elevation = False, **kwargs) Read an TF response file. .. note:: Currently only .edi, .xml, .j, .zmm/rr/ss, .avg files are supported :param fn: Full path to input file. :type fn: str | Path | None :param file_type: Type of file to read. If None, automatically detects file type by the extension. Options are [edi | j | xml | avg | zmm | zrr | zss | ...] :type file_type: str | None :param get_elevation: Whether to get elevation from US National Map DEM :type get_elevation: bool :param : >>> import mt_metadata.transfer_functions import TF >>> tf_obj = TF() >>> tf_obj.read(fn=r"/home/mt/mt01.xml") :type : Example: :: :param .. note:: If your internet is slow try setting 'get_elevation' = False: It can get hooked in a slow loop and slow down reading. :param : It can get hooked in a slow loop and slow down reading. .. py:method:: to_edi() Convert the TF object to a :class:`mt_metadata.transfer_functions.io.edi.EDI` object. From there attributes of an EDI object can be manipulated previous to writing to a file. :rtype: EDI object >>> from mt_metadata.transfer_functions import TF >>> from mt_metadata import TF_XML >>> t = TF(TF_XML) >>> t.read() >>> edi_object = t.to_edi() >>> edi_object.Header.acqby = "me" >>> edi_object.write() .. py:method:: from_edi(edi_obj, get_elevation = False, **kwargs) Read in an EDI file or a :class:`mt_metadata.transfer_functions.io.edi.EDI` object :param edi_obj: Path to EDI file or EDI object If a path is provided, the file will be read from disk. If an EDI object is provided, it will be used directly. :type edi_obj: str | Path | EDI :param get_elevation: Try to get elevation from US National Map, defaults to False :type get_elevation: bool :raises TypeError: If input is incorrect .. py:method:: to_emtfxml() Convert TF to a :class:`mt_metadata.transfer_function.io.emtfxml.EMTFXML` object. :returns: * *return: EMTFXML object* * rtype: :class:`mt_metadata.transfer_function.io.emtfxml.EMTFXML` * *>>> from mt_metadata.transfer_functions import TF* * *>>> from mt_metadata import TF_XML* * *>>> t = TF(TF_XML)* * *>>> t.read()* * *>>> xml_object = t.to_emtfxml()* * *>>> xml_object.site.country = "Here"* * *>>> xml_object.write()* .. py:method:: from_emtfxml(emtfxml_obj, get_elevation = False, **kwargs) :param emtfxml_obj: The input object to convert from. :type emtfxml_obj: str | Path | EMTFXML :param get_elevation: Try to get elevation from US National Map, defaults to True. :type get_elevation: bool :rtype: None .. py:method:: to_jfile() :abstractmethod: Translate TF object ot JFile object. .. note:: Not Implemented yet :return: JFile object :rtype: :class:`mt_metadata.transfer_functions.io.jfile.JFile` .. py:method:: from_jfile(j_obj, get_elevation = False, **kwargs) :param jfile_obj: The input object to convert from. :type jfile_obj: str | Path | JFile :param get_elevation: Try to get elevation from US National Map, defaults to True. :type get_elevation: bool :rtype: None .. py:method:: make_zmm_run(zmm_obj, number_dict) Helper function to provide a run for a zmm object to aid writing z-file :param zmm_obj: A ZMM that will be written to file, that needs a run associated. :type zmm_obj: ZMM :param number_dict: Mapping between hexy keys and integers, needed for emtf z-files, e.g. {"hx": 1, "hy": 2, "hz": 3, "ex": 4, "ey": 5} :type number_dict: dict :param : :type : type number_dict: dictionary :param : :type : return: run :param : :type : rtype: :class:` mt_metadata.timeseries.run.Run` .. py:method:: to_zmm() Translate TF object to ZMM object. :return: ZMM object :rtype: :class:`mt_metadata.transfer_function.io.zfiles.ZMM` >>> from mt_metadata.transfer_functions import TF >>> from mt_metadata import TF_XML >>> t = TF(TF_XML) >>> t.read() >>> zmm_object = t.to_zmm() >>> zmm_object.processing_type = "new and fancy" >>> zmm_object.write() .. py:method:: from_zmm(zmm_obj, get_elevation = False, **kwargs) :param zmm_obj: Path to .zmm file or ZMM object :type zmm_obj: str | Path | ZMM :param get_elevation: Try to get elevation from US National Map, defaults to True :type get_elevation: bool :param kwargs: Keyword arguments for ZMM object Can include channel_nomenclature, inverse_channel_nomenclature rotate_to_measurement_coordinates : bool, optional If True, rotate impedance to the provided reference frame of the channel metadata, by default True use_declination : bool, optional If True, rotate impedance to true north using declination value in metadata, by default False :type kwargs: dict .. py:method:: to_zrr() Translate TF object to ZMM object. :return: ZMM object :rtype: :class:`mt_metadata.transfer_function.io.zfiles.ZMM` >>> from mt_metadata.transfer_functions import TF >>> from mt_metadata import TF_XML >>> t = TF(TF_XML) >>> t.read() >>> zmm_object = t.to_zmm() >>> zmm_object.processing_type = "new and fancy" >>> zmm_object.write() .. py:method:: from_zrr(zrr_obj, get_elevation = False, **kwargs) :param zmm_obj: Path to .zmm file or ZMM object :type zmm_obj: str | Path | ZMM :param get_elevation: Try to get elevation from US National Map, defaults to True :type get_elevation: bool :param kwargs: Keyword arguments for ZMM object :type kwargs: dict .. py:method:: to_zss() Translate TF object to ZMM object. :return: ZMM object :rtype: :class:`mt_metadata.transfer_function.io.zfiles.ZMM` >>> from mt_metadata.transfer_functions import TF >>> from mt_metadata import TF_XML >>> t = TF(TF_XML) >>> t.read() >>> zmm_object = t.to_zmm() >>> zmm_object.processing_type = "new and fancy" >>> zmm_object.write() .. py:method:: from_zss(zss_obj, get_elevation = False, **kwargs) :param zss_obj: Path to .zss file or ZMM object :type zss_obj: str | Path | ZMM :param get_elevation: Try to get elevation from US National Map, defaults to True :type get_elevation: bool .. py:method:: to_avg() Translate TF object to ZongeMTAvg object. .. note:: Not Implemented yet :return: ZongeMTAvg object :rtype: :class:`mt_metadata.transfer_function.io.zonge.ZongeMTAvg` .. py:method:: from_avg(avg_obj, get_elevation = False, **kwargs) :param avg_obj: Path to .avg file or ZongeMTAvg object :type avg_obj: str | Path | ZongeMTAvg :param get_elevation: Try to get elevation from US National Map, defaults to True :type get_elevation: bool