simpeg / aurora

software for processing natural source electromagnetic data
MIT License
14 stars 2 forks source link

Deprecate TransferFunctionHeader Class #109

Closed kkappler closed 1 year ago

kkappler commented 2 years ago

See Issue #18. The TransferFunctionHeader object is not needed as we get this information from the mth5 now as dictionaries.

If we want to eliminate TransferFunctionHeader, we need to change the places where the code uses it to get that data from another object. The TransferFunction object would need to be able to provide:

  1. A list of input channels
  2. A list of output channels
  3. a property that returns num_input_channels and num_output_channels bases on 1,2, above.
  4. local_station_id
  5. TransferFunctionCollection will need to get its "header" from the TransferFunction object
    • Note that TransferFunctionCollection also only needs to access input_channels, output_channels, and local_station_id
  6. Finally, the class should be moved into sandbox before deprecation as it does get used in the one-off function aurora/sandbox/io_helpers/matlab_z_file_reader.py which reads matlab structs, and is also slated for deprecation.

Helpers in coding this: rgreppy tf_header yields:

aurora/sandbox/io_helpers/matlab_z_file_reader.py:101:tfc = TransferFunctionCollection(header=tf_obj.tf_header, tf_dict=tf_dict)
aurora/sandbox/.ipynb_checkpoints/plot_helpers-checkpoint.py:45:    ttl_str = tf_obj.tf_header.local_station_id
aurora/sandbox/plot_helpers.py:48:    ttl_str = tf_obj.tf_header.local_station_id
aurora/transfer_function/transfer_function_collection.py:56:        return self.tf_dict[0].tf_header.local_station_id
aurora/transfer_function/transfer_function_collection.py:379:                for out_ch in tf.tf_header.output_channels:
aurora/transfer_function/transfer_function_collection.py:380:                    for inp_ch in tf.tf_header.input_channels:
aurora/transfer_function/transfer_function_collection.py:392:                for i, inp_ch1 in enumerate(tf.tf_header.input_channels):
aurora/transfer_function/transfer_function_collection.py:393:                    for inp_ch2 in tf.tf_header.input_channels[: i + 1]:
aurora/transfer_function/transfer_function_collection.py:407:                for i, out_ch1 in enumerate(tf.tf_header.output_channels):
aurora/transfer_function/transfer_function_collection.py:408:                    for out_ch2 in tf.tf_header.output_channels[: i + 1]:
aurora/transfer_function/transfer_function_collection.py:537:        ttl_str = f"{tf.tf_header.local_station_id} {xy_or_yx} \n{ttl_str}"
aurora/transfer_function/transfer_function_collection.py:549:        # figure_basename = f"synthetic_{tf.tf_header.local_station_id}_{xy_or_yx}.png"
aurora/transfer_function/base.py:66:    def __init__(self, tf_header, frequency_bands, **kwargs):
aurora/transfer_function/base.py:76:        tf_header
aurora/transfer_function/base.py:80:        self.tf_header = tf_header
aurora/transfer_function/base.py:89:        if self.tf_header is not None:
aurora/transfer_function/base.py:138:        if self.tf_header is None:
aurora/transfer_function/base.py:151:                "output_channel": self.tf_header.output_channels,
aurora/transfer_function/base.py:152:                "input_channel": self.tf_header.input_channels,
aurora/transfer_function/base.py:165:                "channel": self.tf_header.output_channels,
aurora/transfer_function/base.py:178:                "input_channel_1": self.tf_header.input_channels,
aurora/transfer_function/base.py:179:                "input_channel_2": self.tf_header.input_channels,
aurora/transfer_function/base.py:192:                "output_channel_1": self.tf_header.output_channels,
aurora/transfer_function/base.py:193:                "output_channel_2": self.tf_header.output_channels,
aurora/transfer_function/base.py:204:                "output_channel": self.tf_header.output_channels,
aurora/transfer_function/base.py:221:        return self.tf_header.num_input_channels
aurora/transfer_function/base.py:225:        return self.tf_header.num_output_channels
aurora/transfer_function/base.py:297:                "output_channel": self.tf_header.output_channels,
aurora/transfer_function/base.py:298:                "input_channel": self.tf_header.input_channels,
aurora/transfer_function/base.py:302:        for out_ch in self.tf_header.output_channels:
aurora/transfer_function/base.py:303:            for inp_ch in self.tf_header.input_channels:
aurora/pipelines/process_mth5.py:329:    tf_collection = TransferFunctionCollection(header=tf_obj.tf_header, tf_dict=tf_dict)

rgreppy TransferFunctionHeader yields:

aurora/sandbox/io_helpers/matlab_z_file_reader.py:16:from aurora.transfer_function.transfer_function_header import TransferFunctionHeader
aurora/sandbox/io_helpers/matlab_z_file_reader.py:35:    transfer_function_header = TransferFunctionHeader(
aurora/transfer_function/transfer_function_collection.py:4:1. TransferFunctionHeader
aurora/transfer_function/transfer_function_header.py:7:class TransferFunctionHeader(object):
aurora/transfer_function/base.py:43:    Header : transfer_function_header.TransferFunctionHeader() object.
aurora/pipelines/transfer_function_helpers.py:12:from aurora.transfer_function.transfer_function_header import TransferFunctionHeader
aurora/pipelines/transfer_function_helpers.py:64:    transfer_function_header = TransferFunctionHeader(
kkappler commented 1 year ago

This is actually a somewhat handy convenience class, the issue is that it duplicates data that are available elsewhere, in particular, all the data in this object seems to come from the processing Config()

Thus, it would be best if this class were always generated by the processing config.
Doing this "Consolidation before deprecation" will allow deprecation to focusing only on that one generator.

The TransferFunctionHeader attrs that are called are the following:

kkappler commented 1 year ago

Transfer Function Header is now consolidated into something that is generated as a method of Processing class.

The only change to still consider is making this a dict rather than a class - changing it to an mt_metadata object. However, that task will be more easily done while migrating the Processing class into mt_metadata which is o be addressed during the FC implementation.

kkappler commented 1 year ago

If aurora's transfer_function class always has a processing_scheme instantiated when header is called, we can access header that way, via a method inside the transfer_function base class. This will eliminate tf_header as an input argument, and simplify its usage.

To make this all work on the new fc branches, which should import the processing scheme from mt_metadata, and to avoid circular imports (from aurora) we will need to make TransferFunctionHeader a class that lives in mt_metadata.

A good candidate for this would be a ListDict (or python-box)

kkappler commented 1 year ago

This class has been completely deprecated and replaced with a ListDict that is returned by the emtf_tf_header method in processing.py

kkappler commented 1 year ago

This class has been completely deprecated and replaced with a ListDict that is returned by the emtf_tf_header method in processing.py