mt_metadata.processing.aurora ============================= .. py:module:: mt_metadata.processing.aurora Submodules ---------- .. toctree:: :maxdepth: 1 /source/api/mt_metadata/processing/aurora/channel/index /source/api/mt_metadata/processing/aurora/channel_nomenclature/index /source/api/mt_metadata/processing/aurora/decimation_level/index /source/api/mt_metadata/processing/aurora/estimator/index /source/api/mt_metadata/processing/aurora/frequency_bands/index /source/api/mt_metadata/processing/aurora/processing/index /source/api/mt_metadata/processing/aurora/regression/index /source/api/mt_metadata/processing/aurora/run/index /source/api/mt_metadata/processing/aurora/station/index /source/api/mt_metadata/processing/aurora/stations/index Classes ------- .. autoapisummary:: mt_metadata.processing.aurora.Band mt_metadata.processing.aurora.Channel mt_metadata.processing.aurora.ChannelNomenclature mt_metadata.processing.aurora.DecimationLevel mt_metadata.processing.aurora.Estimator mt_metadata.processing.aurora.FrequencyBands mt_metadata.processing.aurora.Processing mt_metadata.processing.aurora.Regression mt_metadata.processing.aurora.Run mt_metadata.processing.aurora.Station mt_metadata.processing.aurora.Stations Package Contents ---------------- .. py:class:: Band(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: decimation_level :type: Annotated[int, Field(default=None, description='Decimation level for the band', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['0']})] .. py:attribute:: index_max :type: Annotated[int, Field(default=None, description='maximum band index', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:attribute:: index_min :type: Annotated[int, Field(default=None, description='minimum band index', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:attribute:: frequency_max :type: Annotated[float, Field(default=0.0, description='maximum band frequency', alias=None, json_schema_extra={'units': 'Hertz', 'required': True, 'examples': ['0.04296875']})] .. py:attribute:: frequency_min :type: Annotated[float, Field(default=0.0, description='minimum band frequency', alias=None, json_schema_extra={'units': 'Hertz', 'required': True, 'examples': ['0.03515625']})] .. py:attribute:: center_averaging_type :type: Annotated[CenterAveragingTypeEnum, Field(default=CenterAveragingTypeEnum.geometric, description='type of average to apply when computing the band center', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['geometric']})] .. py:attribute:: closed :type: Annotated[ClosedEnum, Field(default=ClosedEnum.left, description='whether interval is open or closed', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['left']})] .. py:attribute:: name :type: Annotated[Optional[str], Field(default='', description='Name of the band', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['0.039062']})] .. py:method:: validate_name(value, info) :classmethod: .. py:method:: update_name_on_frequency_change(value, info) :classmethod: .. py:method:: check_name() .. py:property:: lower_bound :type: float .. py:property:: upper_bound :type: float .. py:property:: width :type: float returns the width of the band (the bandwidth). .. py:property:: lower_closed :type: bool .. py:property:: upper_closed :type: bool .. py:method:: set_indices_from_frequencies(frequencies) assumes min/max freqs are defined .. py:method:: to_interval() .. py:property:: harmonic_indices Assumes all harmoincs between min and max are present in the band :rtype: numpy array of integers corresponding to harminic indices .. py:method:: in_band_harmonics(frequencies) :param frequencies: :type frequencies: array-like, floating poirt :param Returns: the actual harmonics or frequencies in band, rather than the indices. :type Returns: numpy array :param -------: .. py:property:: center_frequency :type: float returns: **center_frequency** -- The frequency associated with the band center. :rtype: float .. py:property:: center_period :type: float Returns the inverse of center frequency. .. py:method:: overlaps(other) Check if this band overlaps with another .. py:method:: contains(other) Check if this band contains nother .. py:property:: fractional_bandwidth :type: float See - https://en.wikipedia.org/wiki/Bandwidth_(signal_processing)#Fractional_bandwidth - https://en.wikipedia.org/wiki/Q_factor .. py:property:: Q :type: float Quality factor (Q) of the band. :returns: Q factor. Returns infinity for zero-width bands. :rtype: float .. py:class:: Channel(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: id :type: Annotated[str, Field(default='', description='channel ID', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['mt001']})] .. py:attribute:: scale_factor :type: Annotated[float, Field(default=1.0, description='scale factor of the channel', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10.0']})] .. py:class:: ChannelNomenclature(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: ex :type: Annotated[ExEnum, Field(default='ex', description='label for the X electric field channel, X is assumed to be North', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['ex']})] .. py:attribute:: ey :type: Annotated[EyEnum, Field(default='ey', description='label for the Y electric field channel, Y is assumed to be East', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['ey']})] .. py:attribute:: hx :type: Annotated[HxEnum, Field(default='hx', description='label for the X magnetic field channel, X is assumed to be North', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hx']})] .. py:attribute:: hy :type: Annotated[HyEnum, Field(default='hy', description='label for the Y magnetic field channel, Y is assumed to be East', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hy']})] .. py:attribute:: hz :type: Annotated[HzEnum, Field(default='hz', description='label for the Z magnetic field channel, Z is assumed to be vertical Down', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hz']})] .. py:attribute:: keyword :type: Annotated[SupportedNomenclatureEnum, Field(default=SupportedNomenclatureEnum.default, description='Keyword for the channel nomenclature system', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['default', 'lemi12', 'lemi34', 'musgraves', 'phoenix123']})] .. py:method:: check_keyword(value, info) :classmethod: .. py:property:: ex_ey :type: list[str] .. py:property:: hx_hy :type: list[str] .. py:property:: hx_hy_hz :type: list[str] .. py:property:: ex_ey_hz :type: list[str] .. py:property:: default_input_channels :type: list[str] .. py:property:: default_output_channels :type: list[str] .. py:property:: default_reference_channels :type: list[str] .. py:method:: get_channel_map() Based on self.keyword return the mapping between conventional channel names and the custom channel names in the particular nomenclature. .. py:method:: update() Assign values to standard channel names "ex", "ey" etc based on channel_map dict .. py:method:: unpack() .. py:property:: channels :type: list[str] .. py:method:: model_post_init(__context) Called after model initialization to set up auto-update and do initial update. .. py:class:: DecimationLevel(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: bands :type: Annotated[list[mt_metadata.common.band.Band], Field(default_factory=list, description='List of bands', json_schema_extra={'units': None, 'required': True, 'examples': ['[]']})] .. py:attribute:: channel_weight_specs :type: Annotated[List[mt_metadata.features.weights.ChannelWeightSpec], Field(default_factory=list, description='List of weighting schemes to use for TF processing for each output channel', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['[]']})] .. py:attribute:: input_channels :type: Annotated[list[str], Field(default_factory=list, description='list of input channels (sources)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hx, hy']})] .. py:attribute:: output_channels :type: Annotated[list[str], Field(default_factory=list, description='list of output channels (responses)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['ex, ey, hz']})] .. py:attribute:: reference_channels :type: Annotated[list[str], Field(default_factory=list, description='list of reference channels (remote sources)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hx, hy']})] .. py:attribute:: save_fcs :type: Annotated[bool, Field(default=False, description='Whether the Fourier coefficients are saved [True] or not [False].', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': [True]})] .. py:attribute:: save_fcs_type :type: Annotated[SaveFcsTypeEnum | None, Field(default=None, description='Format to use for fc storage', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['h5']})] .. py:attribute:: decimation :type: Annotated[mt_metadata.processing.TimeSeriesDecimation, Field(default_factory=Decimation, description='Decimation settings', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Decimation()']})] .. py:attribute:: estimator :type: Annotated[mt_metadata.processing.aurora.estimator.Estimator, Field(default_factory=Estimator, description='Estimator settings', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Estimator()']})] .. py:attribute:: regression :type: Annotated[mt_metadata.processing.aurora.regression.Regression, Field(default_factory=Regression, description='Regression settings', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Regression()']})] .. py:attribute:: stft :type: Annotated[mt_metadata.processing.ShortTimeFourierTransform, Field(default_factory=STFT, description='Short-time Fourier transform settings', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['STFT()']})] .. py:method:: validate_channel_weight_specs(value, info) :classmethod: Validator for channel_weight_specs field. .. py:method:: validate_bands(value, info) :classmethod: .. py:method:: add_band(band) add a band .. py:property:: lower_bounds :type: numpy.ndarray get lower bounds index values into an array. .. py:property:: upper_bounds :type: numpy.ndarray get upper bounds index values into an array. .. py:property:: bands_dataframe :type: pandas.DataFrame Utility function that transforms a list of bands into a dataframe See notes in `_df_from_bands`. :returns: **bands_df** -- Same format as that generated by EMTFBandSetupFile.get_decimation_level() :rtype: pd.Dataframe .. py:property:: frequency_sample_interval :type: float Returns the delta_f in frequency domain df = 1 / (N * dt) Here dt is the sample interval after decimation :returns: **frequency_sample_interval** -- The frequency sample interval after decimation. :rtype: float .. py:property:: band_edges :type: numpy.ndarray Returns the band edges as a numpy array :returns: **band_edges** :rtype: 2D numpy array, one row per frequency band and two columns .. py:method:: frequency_bands_obj() Gets a FrequencyBands object that is used as input to processing. Used by Aurora. TODO: consider adding .to_frequency_bands() method directly to self.bands :returns: **frequency_bands** -- A FrequencyBands object that can be used as an iterator for processing. :rtype: FrequencyBands .. py:property:: fft_frequencies :type: numpy.ndarray Gets the harmonics of the STFT. :returns: **freqs** -- The frequencies at which the stft will be available. :rtype: np.ndarray .. py:property:: harmonic_indices :type: List[int] Loops over all bands and returns a list of the harminic indices. TODO: Distinguish the bands which are a processing construction vs harmonic indices which are FFT info. :returns: **return_list** -- The indices of the harmonics that are needed for processing. :rtype: list of integers .. py:property:: local_channels .. py:method:: is_consistent_with_archived_fc_parameters(fc_decimation, remote) Usage: For an already existing spectrogram stored in an MTH5 archive, this compares the metadata within the archive (fc_decimation) with an aurora decimation level (self), and tells whether the parameters are in agreement. If True, this allows aurora to skip the calculation of FCs and instead read them from the archive. TODO: Merge all checks of TimeSeriesDecimation parameters into a single check. - e.g. Compress all decimation checks to: assert fc_decimation.decimation == self.decimation Parameters ---------- decimation_level: FCDecimation metadata describing the parameters used to compute an archived spectrogram remote: bool If True, we are looking for reference channels, not local channels in the FCGroup. Iterates over FCDecimation attributes: "channels_estimated": to ensure all expected channels are in the group "decimation.anti_alias_filter": check that the expected AAF was applied "decimation.sample_rate, "decimation.method", "stft.prewhitening_type", "stft.recoloring", "stft.pre_fft_detrend_type", "stft.min_num_stft_windows", "stft.window", "stft.harmonic_indices", :rtype: return: .. py:method:: to_fc_decimation(remote = False, ignore_harmonic_indices = True) Generates a FC Decimation() object for use with FC Layer in mth5. TODO: this is being tested only in aurora -- move a test to mt_metadata or move the method. Ignoring for now these properties "time_period.end": "1980-01-01T00:00:00+00:00", "time_period.start": "1980-01-01T00:00:00+00:00", TODO: FIXME: Assignment of TSDecimation can be done in one shot once #235 is addressed. :param remote: If True, use reference channels, if False, use local_channels. We may wish to not pass remote=True when _building_ FCs however, because then not all channels will get built. :type remote: bool :param ignore_harmonic_indices: If True, leave harmonic indices at default [-1,], which means all indices. If False, only the specific harmonic indices needed for processing will be stored. Thus, when building FCs, it maybe best to leave this as True, that way all FCs will be stored, so if the band setup is changed, the FCs will still be there. :type ignore_harmonic_indices: bool :param Returns: fc_dec_obj:mt_metadata.transfer_functions.processing.fourier_coefficients.decimation.Decimation A decimation object configured for STFT processing .. py:class:: Estimator(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: engine :type: Annotated[EngineEnum, Field(default=EngineEnum.RME_RR, description='The transfer function estimator engine', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['RME_RR']})] .. py:attribute:: estimate_per_channel :type: Annotated[bool, Field(default=True, description='Estimate per channel', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['True']})] .. py:class:: FrequencyBands(band_edges = None) Collection of Band objects, typically used at a single decimation level. .. attribute:: _band_edges DataFrame with columns ['lower_bound', 'upper_bound'] containing frequency band boundaries :type: pd.DataFrame .. py:property:: band_edges :type: pandas.DataFrame Get band edges as a DataFrame .. py:property:: number_of_bands :type: int Number of frequency bands .. py:property:: array :type: numpy.ndarray Get band edges as numpy array .. py:method:: sort(by = 'center_frequency', ascending = True) Sort bands by specified criterion. :param by: Criterion to sort by: - "lower_bound": Sort by lower frequency bound - "upper_bound": Sort by upper frequency bound - "center_frequency": Sort by geometric center frequency (default) :type by: str :param ascending: If True, sort in ascending order, else descending :type ascending: bool .. py:method:: bands(direction = 'increasing_frequency', sortby = None, rtype = 'list') Generate Band objects in specified order. :param direction: Order of iteration: "increasing_frequency" or "increasing_period" :type direction: str :param sortby: Sort bands before iteration: - "lower_bound": Sort by lower frequency bound - "upper_bound": Sort by upper frequency bound - "center_frequency": Sort by geometric center frequency If None, uses existing order :type sortby: str, optional :param rtype: Return type: "list" or "generator". Default is "list" for easier reuse. Use "generator" for memory efficiency when bands are only iterated once. :type rtype: str :returns: Band objects for each frequency band, either as a list or generator depending on rtype parameter. :rtype: Union[List[Band], Generator[Band, None, None]] .. py:method:: band(i_band) Get specific frequency band. :param i_band: Index of band to return (zero-based) :type i_band: int :returns: Frequency band object :rtype: Band .. py:method:: band_centers(frequency_or_period = 'frequency') Calculate center frequencies/periods for all bands. :param frequency_or_period: Return values in "frequency" (Hz) or "period" (s) :type frequency_or_period: str :returns: Center frequencies/periods for each band :rtype: np.ndarray .. py:method:: validate() Validate and potentially reorder bands based on center frequencies. .. py:class:: Processing(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: decimations :type: Annotated[list[mt_metadata.processing.aurora.decimation_level.DecimationLevel], Field(default_factory=list, description='decimation levels', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['0']})] .. py:attribute:: band_specification_style :type: Annotated[BandSpecificationStyleEnum | None, Field(default=None, description='describes how bands were sourced', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['EMTF']})] .. py:attribute:: band_setup_file :type: Annotated[str | None, Field(default=None, description='the band setup file used to define bands', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['/home/user/bs_test.cfg']})] .. py:attribute:: id :type: Annotated[str, Field(default='', description='Configuration ID', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['0']})] .. py:attribute:: channel_nomenclature :type: Annotated[mt_metadata.processing.aurora.channel_nomenclature.ChannelNomenclature, Field(default_factory=ChannelNomenclature, description='Channel nomenclature', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['EMTF']})] .. py:attribute:: stations :type: Annotated[mt_metadata.processing.aurora.stations.Stations, Field(default_factory=Stations, description='Station information', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['Station1', 'Station2']})] .. py:method:: validate_decimations(value, info) :classmethod: .. py:property:: decimations_dict :type: dict[int, mt_metadata.processing.aurora.decimation_level.DecimationLevel] need to have a dictionary, but it can't be an attribute cause that gets confusing when reading in a json file :returns: A dictionary mapping decimation levels to their corresponding DecimationLevel objects. :rtype: dict[int, DecimationLevel] .. py:method:: get_decimation_level(level) Get a decimation level for easy access :param level: The decimation level to retrieve. :type level: int :returns: The DecimationLevel object corresponding to the specified level. :rtype: DecimationLevel .. py:method:: add_decimation_level(decimation_level) add a decimation level :param decimation_level: The decimation level to add, either as a DecimationLevel object or a dictionary. :type decimation_level: DecimationLevel | dict :rtype: None .. py:property:: band_edges_dict :type: dict[int, list[tuple[float, float]]] .. py:method:: assign_decimation_level_data_emtf(sample_rate) Warning: This does not actually tell us how many samples we are decimating down at each level. That is assumed to be 4 but we need a way to bookkeep this in general :param sample_rate: The initial sampling rate of the data before any decimation :type sample_rate: float .. py:method:: assign_bands(band_edges_dict, sample_rate, decimation_factors, num_samples_window = 256) Warning: This does not actually tell us how many samples we are decimating down at each level. That is assumed to be 4 but we need a way to bookkeep this in general :param band_edges: A dictionary mapping decimation levels to lists of frequency band edges. keys are integers, starting with 0, values are arrays of edges :type band_edges: dict[int, list[tuple[float, float]]] :param sample_rate: The initial sampling rate of the data before any decimation. :type sample_rate: float :param decimation_factors: A dictionary mapping decimation levels to their corresponding decimation factors. :type decimation_factors: dict[int, int] :param num_samples_window: The number of samples in the STFT window for each decimation level. If an integer is provided, it will be applied to all levels. If a dictionary is provided, it should map decimation levels to their corresponding number of samples. :type num_samples_window: dict[int, int] | int, optional (default=256) :rtype: None .. py:method:: json_fn() .. py:property:: num_decimation_levels .. py:method:: drop_reference_channels() .. py:method:: set_input_channels(channels) .. py:method:: set_output_channels(channels) .. py:method:: set_reference_channels(channels) .. py:method:: set_default_input_output_channels() .. py:method:: set_default_reference_channels() .. py:method:: validate_processing(kernel_dataset) Placeholder. Some of the checks and methods here maybe better placed in TFKernel, which would validate the dataset against the processing config. Things that are validated: 1. The default estimation engine from the json file is "RME_RR", which is fine ( we expect to in general to do more RR processing than SS) but if there is only one station (no remote)then the RME_RR should be replaced by default with "RME". 2. make sure local station id is defined (correctly from kernel dataset) .. py:class:: Regression(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: minimum_cycles :type: Annotated[int, Field(default=1, description='Minimum number of cycles in the regression', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:attribute:: max_iterations :type: Annotated[int, Field(default=10, description='Max iterations of the regression', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:attribute:: max_redescending_iterations :type: Annotated[int, Field(default=2, description='Max redescending iterations of the regression', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['2']})] .. py:attribute:: r0 :type: Annotated[float, Field(default=1.5, description='The number of standard deviations where the influence function changes from linear to quadratic', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['1.4']})] .. py:attribute:: u0 :type: Annotated[float, Field(default=2.8, description='Control for redescending Huber regression weights.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['2.8']})] .. py:attribute:: tolerance :type: Annotated[float, Field(default=0.005, description='Control for convergence of RME algorithm. Lower means more iterations', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['0.005']})] .. py:attribute:: verbosity :type: Annotated[int, Field(default=1, description='Control for logging messages during regression -- Higher means more messages', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['1']})] .. py:class:: Run(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: id :type: Annotated[str, Field(default='', description='run ID', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['001']})] .. py:attribute:: input_channels :type: Annotated[list[mt_metadata.processing.aurora.channel.Channel], Field(default_factory=list, description='List of input channels (source)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['hx, hy']})] .. py:attribute:: output_channels :type: Annotated[list[mt_metadata.processing.aurora.channel.Channel], Field(default_factory=list, description='List of output channels (response)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['ex, ey, hz']})] .. py:attribute:: time_periods :type: Annotated[list[mt_metadata.common.TimePeriod], Field(default_factory=list, description='List of time periods to process', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ["[{'start': '2020-01-01T00:00:00', 'end': '2020-01-01T01:00:00'}]"]})] .. py:attribute:: sample_rate :type: Annotated[float, Field(default=1.0, description='sample rate of the run', alias=None, json_schema_extra={'units': 'samples per second', 'required': True, 'examples': ['1']})] .. py:method:: validate_channel_list(values, info) :classmethod: .. py:method:: validate_time_periods(values, info) :classmethod: .. py:property:: channel_scale_factors :type: dict[str, float] .. py:method:: set_channel_scale_factors(values) Validate and process channel scale factors. :param values: The scale factors for the channels. :type values: Union[dict, float] :raises TypeError: If the input is not a dictionary or float. .. py:property:: input_channel_names :type: list[str] list of channel names .. py:property:: output_channel_names :type: list[str] list of channel names .. py:class:: Station(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: id :type: Annotated[str, Field(default='', description='Station ID', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['mt001']})] .. py:attribute:: mth5_path :type: Annotated[str | pathlib.Path, Field(default='', description='full path to MTH5 file where the station data is contained', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['/home/mt/experiment_01.h5']})] .. py:attribute:: remote :type: Annotated[bool, Field(default=False, description='remote station (True) or local station (False)', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['False']})] .. py:attribute:: runs :type: Annotated[list[mt_metadata.processing.aurora.run.Run], Field(default_factory=list, description='List of runs to process', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['001']})] .. py:method:: validate_mth5_path(value, info) :classmethod: .. py:method:: validate_runs(values, info) :classmethod: .. py:method:: get_run(run_id) Get a run by ID :param run_id: DESCRIPTION :type run_id: TYPE :returns: DESCRIPTION :rtype: Run | None .. py:property:: run_list :type: list[str] list of run names .. py:property:: run_dict :type: dict[str, mt_metadata.processing.aurora.run.Run] need to have a dictionary, but it can't be an attribute cause that gets confusing when reading in a json file :returns: DESCRIPTION :rtype: dict[str, Run] .. py:method:: to_dataset_dataframe() Create a dataset definition dataframe that can be used in the processing [ "station", "run", "start", "end", "mth5_path", "sample_rate", "input_channels", "output_channels", "remote", ] .. py:method:: from_dataset_dataframe(df) set a data frame [ "station", "run", "start", "end", "mth5_path", "sample_rate", "input_channels", "output_channels", "remote", ] :param df: DESCRIPTION :type df: pd.DataFrame :returns: DESCRIPTION :rtype: TYPE .. py:class:: Stations(**data) Bases: :py:obj:`mt_metadata.base.MetadataBase` Base class for all metadata objects with Pydantic validation. MetadataBase extends DotNotationBaseModel (which inherits from Pydantic's BaseModel) to provide automatic validation according to metadata standards. It adds functionality beyond dictionaries, supporting JSON, XML, pandas Series, and other formats for metadata interchange. .. attribute:: _skip_equals Private attribute listing fields to skip in equality comparisons :type: list[str] .. attribute:: _fields Private attribute caching field information :type: dict[str, Any] .. rubric:: Notes - All field assignments are validated automatically via Pydantic - None values are converted to appropriate defaults (empty string or 0.0) - Supports nested attribute access via dot notation - Thread-safe for read operations after initialization .. py:attribute:: remote :type: Annotated[list[mt_metadata.processing.aurora.station.Station], Field(default_factory=list, description='list of remote sites', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:attribute:: local :type: Annotated[mt_metadata.processing.aurora.station.Station, Field(default_factory=Station, description='local site', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['10']})] .. py:method:: validate_remote(value, info) Method for unpacking rr_station info into mt_metadata object. Developmnent Notes: This function was raising an exception when trying to populate an aurora.Processing object from a json.loads() dict. TODO: add a description of input variable and use cases, ... it seems that we may not want to support multiple rr stations yet. :param rr_station: :rtype: list of Station objects .. py:method:: add_remote(rr) add a remote station :param rr: remote station to add :type rr: Station | dict .. py:property:: remote_dict :type: dict[str, mt_metadata.processing.aurora.station.Station] need to have a dictionary, but it can't be an attribute cause that gets confusing when reading in a json file :returns: dictionary of remote stations :rtype: dict[str, Station] .. py:method:: from_dataset_dataframe(df) from a dataset dataframe :param df: dataset dataframe to read from :type df: pd.DataFrame :rtype: None .. py:method:: to_dataset_dataframe() output a dataframe :returns: dataframe representation of the station :rtype: pd.DataFrame .. py:method:: get_station(station_id) get a station object from the id :param station_id: ID of the station to retrieve :type station_id: str :returns: Station object corresponding to the given ID :rtype: Station