mt_metadata.timeseries
mt_metadata.timeseries is a package that contains classes for
describing time series metadata.
MetadataBase Objects
Diagnostic - Diagnostic information for data quality and instrument performance
Battery - Battery voltage and power supply metadata
Electrode - Electrode specifications and contact information
TimingSystem - GPS and timing system metadata (synchronization, accuracy)
AppliedFilter - Filters applied to time series data during acquisition or processing
FilterBase - Base class for all filter types (analog, digital, frequency response)
DataLogger - Data logger/acquisition system specifications and settings
Channel - Base channel metadata common to all channel types
ChannelBase - Fundamental channel properties and attributes
Auxiliary - Auxiliary channel metadata (e.g., temperature, humidity, tilt)
Electric - Electric field channel metadata (dipole length, orientation, electrode info)
Magnetic - Magnetic field channel metadata (sensor type, calibration)
Run - Time series run metadata (collection of channels recorded together)
Station - Station-level metadata (location, orientation, equipment)
Survey - Survey-level metadata (project information, participants, objectives)
Experiment - Top-level experiment metadata encompassing multiple surveys
Created on Sun Apr 24 20:50:41 2020
- copyright:
Jared Peacock (jpeacock@usgs.gov)
- license:
MIT
Submodules
- mt_metadata.timeseries.auxiliary
- mt_metadata.timeseries.battery
- mt_metadata.timeseries.channel
- mt_metadata.timeseries.data_logger
- mt_metadata.timeseries.diagnostic
- mt_metadata.timeseries.electric
- mt_metadata.timeseries.electrode
- mt_metadata.timeseries.experiment
- mt_metadata.timeseries.filtered
- mt_metadata.timeseries.filters
- mt_metadata.timeseries.magnetic
- mt_metadata.timeseries.run
- mt_metadata.timeseries.station
- mt_metadata.timeseries.stationxml
- mt_metadata.timeseries.survey
- mt_metadata.timeseries.timing_system
- mt_metadata.timeseries.tools
Classes
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Positional location of a geographic point |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Auxiliary channel class for storing auxiliary channel information. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Base class for all metadata objects with Pydantic validation. |
|
Top level of the metadata |
Package Contents
- class mt_metadata.timeseries.Diagnostic(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- end: Annotated[float | None, Field(default=None, description='Ending value of a diagnostic measurement.', alias=None, json_schema_extra={'examples': '10', 'type': 'number', 'units': None, 'required': False})] = None
- start: Annotated[float | None, Field(default=None, description='Starting value of a diagnostic measurement.', alias=None, json_schema_extra={'examples': '12.3', 'type': 'number', 'units': None, 'required': False})] = None
- class mt_metadata.timeseries.Battery(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- type: Annotated[str | None, Field(default=None, description='Description of battery type.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'pb-acid gel cell', 'type': 'string'})] = None
- id: Annotated[str | None, Field(default=None, description='battery id', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'battery01', 'type': 'string'})] = None
- voltage: Annotated[mt_metadata.common.StartEndRange, Field(default=StartEndRange(), description='Range of voltages.', alias=None, json_schema_extra={'units': 'volts', 'required': False, 'examples': 'Range(minimum=0.0, maximum=1.0)', 'type': 'object'})]
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=Comment, description='Any comments about the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'ambient air temperature was chilly, ice on cables'})]
- classmethod validate_comments(value, info)
Validate that the value is a valid comment.
- class mt_metadata.timeseries.Electrode(**data)
Bases:
mt_metadata.common.Location,mt_metadata.common.InstrumentPositional location of a geographic point
- class mt_metadata.timeseries.TimingSystem(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=Comment, description='Any comment on the timing system.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'GPS locked with internal quartz clock'})]
- drift: Annotated[float, Field(default=0.0, description='Estimated drift of the timing system.', alias=None, json_schema_extra={'units': 'seconds', 'required': True, 'examples': '0.001'})]
- type: Annotated[str, Field(default='GPS', description='Type of timing system.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': 'GPS'})]
- uncertainty: Annotated[float, Field(default=0.0, description='Estimated uncertainty of the timing system.', alias=None, json_schema_extra={'units': 'seconds', 'required': True, 'examples': '0.0002'})]
- n_satellites: Annotated[int | None, Field(default=None, description='Number of satellites used for timing.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': '6'})]
- classmethod validate_comments(value, info)
Validate that the value is a valid comment.
- class mt_metadata.timeseries.AppliedFilter(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- name: Annotated[str, Field(default=None, description='Name of the filter.', json_schema_extra={'units': None, 'required': True, 'examples': ['low pass']})]
- applied: Annotated[bool, Field(default=True, description='Whether the filter has been applied.', json_schema_extra={'units': None, 'required': True, 'examples': ['True']})]
- stage: Annotated[int | None, Field(default=None, description='Stage of the filter in the processing chain.', json_schema_extra={'units': None, 'required': False, 'examples': [1]})]
- comments: Annotated[mt_metadata.common.comment.Comment, Field(default_factory=lambda: Comment(), description='Any comments on filters.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['low pass is not calibrated']})]
- classmethod validate_comments(value, info)
Validate that the value is a valid comment.
- classmethod validate_name(value, info)
Validate that the name is not empty or whitespace only. Also, replace ‘/’ with ‘ per ‘ and convert to lower case for consistency.
- class mt_metadata.timeseries.FilterBase(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- name: Annotated[str, Field(default='', description='Name of filter applied or to be applied. If more than one filter input as a comma separated list.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': '"lowpass_magnetic"'})]
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=lambda: Comment(), description='Any comments about the filter.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'ambient air temperature'})]
- type: Annotated[str, Field(default='base', description='Type of filter, must be one of the available filters.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': 'fap_table'})]
- units_in: Annotated[str, Field(default='', description="Name of the input units to the filter. Should be all lowercase and separated with an underscore, use 'per' if units are divided and '-' if units are multiplied.", alias=None, json_schema_extra={'units': None, 'required': True, 'examples': 'count'})]
- units_out: Annotated[str, Field(default='', description="Name of the output units. Should be all lowercase and separated with an underscore, use 'per' if units are divided and '-' if units are multiplied.", alias=None, json_schema_extra={'units': None, 'required': True, 'examples': 'millivolt'})]
- calibration_date: Annotated[mt_metadata.common.mttime.MTime | str | float | int | numpy.datetime64 | pandas.Timestamp | None, Field(default_factory=lambda: MTime(time_stamp=None), description='Most recent date of filter calibration in ISO format of YYY-MM-DD.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': '2020-01-01'})]
- gain: Annotated[float, Field(default=1.0, description='scalar gain of the filter across all frequencies, producted with any frequency depenendent terms', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': '1.0'})]
- sequence_number: Annotated[int, Field(default=0, description='Sequence number of the filter in the processing chain.', alias=None, ge=0, json_schema_extra={'units': None, 'required': True, 'examples': 1})]
- classmethod validate_calibration_date(field_value)
- classmethod validate_comments(value, info)
- classmethod validate_type(value, info)
Validate that the type of filter is set to “fir”
- classmethod validate_units(value, info)
validate units base on input string will return the long name
- Parameters:
value (units string) – unit string separated by either ‘/’ for division or ‘ ‘ for multiplication. Or ‘per’ and ‘ ‘, respectively
info (ValidationInfo) – _description_
- Returns:
return the long descriptive name of the unit. For example ‘kilometers’.
- Return type:
str
- property units_in_object: mt_metadata.common.units.Unit
- property units_out_object: mt_metadata.common.units.Unit
- make_obspy_mapping()
- property obspy_mapping
mapping to an obspy filter :rtype: dict
- Type:
return
- property total_gain: float
Total gain of the filter :rtype: float
- Type:
return
- get_filter_description()
- Returns:
predetermined filter description based on the type of filter
- Return type:
string
- classmethod from_obspy_stage(stage, mapping=None)
Expected to return a multiply operation function
- Parameters:
cls (filter object) – a filter object
stage (
obspy.inventory.response.ResponseStage) – Obspy stage filtermapping (dict, optional) – dictionary for mapping from an obspy stage, defaults to None
- Raises:
TypeError – If stage is not a
obspy.inventory.response.ResponseStage- Returns:
the appropriate mt_metadata.timeseries.filter object
- Return type:
mt_metadata.timeseries.filter object
- complex_response(frqs)
- pass_band(frequencies, window_len=5, tol=0.5, **kwargs)
Fast passband estimation using decimation (10-100x faster than original).
Caveat: This should work for most Fluxgate and feedback coil magnetometers, and basically most filters having a “low” number of poles and zeros. This method is not 100% robust to filters with a notch in them.
Try to estimate pass band of the filter from the flattest spots in the amplitude. Instead of checking every frequency point, this decimates the frequency array and only checks a subset of windows. The pass band region is then interpolated across the full array.
The flattest spot is determined by calculating a sliding window with length window_len and estimating normalized std.
..note:: This only works for simple filters with on flat pass band.
- Parameters:
frequencies (np.ndarray) – array of frequencies
window_len (integer) – length of sliding window in points
tol (float) – the ratio of the mean/std should be around 1 tol is the range around 1 to find the flat part of the curve.
- Returns:
pass band frequencies [f_start, f_end]
- Return type:
np.ndarray or None
- generate_frequency_axis(sampling_rate, n_observations)
- plot_response(frequencies, x_units='period', unwrap=True, pb_tol=0.1, interpolation_method='slinear')
- property decimation_active
if decimation is prescribed :rtype: bool
- Type:
return
- class mt_metadata.timeseries.DataLogger(**data)
Bases:
mt_metadata.common.InstrumentBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- timing_system: Annotated[mt_metadata.timeseries.TimingSystem, Field(default_factory=TimingSystem, description='Timing system of the data logger.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'TimingSystem()'})]
- firmware: Annotated[mt_metadata.common.Software, Field(default_factory=Software, description='Firmware of the data logger.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'Software()'})]
- power_source: Annotated[mt_metadata.timeseries.Battery, Field(default_factory=Battery, description='Power source of the data logger.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'Battery()'})]
- data_storage: Annotated[mt_metadata.common.Instrument, Field(default_factory=Instrument, description='Data storage of the data logger.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'Instrument()'})]
- class mt_metadata.timeseries.Channel(**data)
Bases:
ChannelBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- sensor: Annotated[mt_metadata.common.Instrument, Field(default_factory=Instrument, description='Sensor for the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': 'Instrument()'})]
- location: Annotated[mt_metadata.common.BasicLocation, Field(default_factory=BasicLocation, description='Location information for the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['BasicLocation(latitude=0.0, longitude=0.0, elevation=0.0)']})]
- class mt_metadata.timeseries.ChannelBase(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- channel_number: Annotated[int, Field(default=0, description='Channel number on the data logger.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['1']})]
- channel_id: Annotated[str | None, Field(default=None, description='channel id given by the user or data logger', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['1001.11']})]
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=Comment, description='Any comments about the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['ambient air temperature was chilly, ice on cables']})]
- component: Annotated[str, Field(default='auxiliary_default', description="Name of the component measured, can be uppercase and/or lowercase. For now electric channels should start with an 'e' and magnetic channels start with an 'h', followed by the component. If there are multiples of the same channel the name could include an integer. {type}{component}{number} --> Ex01.", alias=None, pattern='\\w+', json_schema_extra={'units': None, 'required': True, 'examples': ['ex']})]
- measurement_azimuth: Annotated[float, Field(default=0.0, description='Horizontal azimuth of the channel in measurement coordinate system spcified in station.orientation.reference_frame. Default reference frame is a geographic right-handed coordinate system with north=0, east=90, vertical=+ downward.', validation_alias=AliasChoices('measurement_azimuth', 'azimuth'), json_schema_extra={'units': 'degrees', 'required': True, 'examples': [0.0]})]
- measurement_tilt: Annotated[float, Field(default=0.0, description='Vertical tilt of the channel in measurement coordinate system specified in station.orientation.reference_frame. Default reference frame is a geographic right-handed coordinate system with north=0, east=90, vertical=+ downward.', validation_alias=AliasChoices('measurement_tilt', 'dip'), json_schema_extra={'units': 'degrees', 'required': True, 'examples': [0]})]
- sample_rate: Annotated[float, Field(default=0.0, description='Digital sample rate', validation_alias=AliasChoices('sample_rate', 'sampling_rate'), json_schema_extra={'units': 'samples per second', 'required': True, 'examples': [8.0]})]
- translated_azimuth: Annotated[float | None, Field(default=None, description='Horizontal azimuth of the channel in translated coordinate system, this should only be used for derived product. For instance if you collected your data in geomagnetic coordinates and then translated them to geographic coordinates you would set measurement_azimuth=0, translated_azimuth=-12.5 for a declination angle of N12.5E.', alias=None, json_schema_extra={'units': 'degrees', 'required': False, 'examples': [0.0]})]
- translated_tilt: Annotated[float | None, Field(default=None, description='Tilt of channel in translated coordinate system, this should only be used for derived product. For instance if you collected your data using a tripod you would set measurement_tilt=45, translated_tilt=0 for a vertical component.', alias=None, json_schema_extra={'units': 'degrees', 'required': False, 'examples': [0.0]})]
- type: Annotated[str, Field(default='base', description='Data type for the channel, should be a descriptive word that a user can understand.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['temperature']})]
- units: Annotated[str, Field(default='', description="Units of the data, should be in SI units and represented as the full name of the unit all lowercase. If a complex unit use 'per' and '-'.", alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['celsius']})]
- data_quality: Annotated[mt_metadata.common.DataQuality, Field(default_factory=DataQuality, description='Data quality for the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['DataQuality()']})]
- filters: Annotated[list[mt_metadata.timeseries.AppliedFilter], Field(default_factory=list, description='Filter data for the channel.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ["AppliedFilter(name='filter_name', applied=True, stage=1)"]})]
- time_period: Annotated[mt_metadata.common.TimePeriod, Field(default_factory=TimePeriod, description='Time period for the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ["TimePeriod(start='2020-01-01', end='2020-12-31')"]})]
- fdsn: Annotated[mt_metadata.common.Fdsn, Field(default_factory=Fdsn, description='FDSN information for the channel.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Fdsn()']})]
- classmethod validate_component(value)
make sure the value is all lower case
- classmethod validate_comments(value, info)
Validate that the value is a valid comment.
- classmethod validate_units(value, info)
validate units base on input string will return the long name
- Parameters:
value (units string) – unit string separated by either ‘/’ for division or ‘ ‘ for multiplication. Or ‘per’ and ‘ ‘, respectively
info (ValidationInfo) – _description_
- Returns:
return the long descriptive name of the unit. For example ‘kilometers’.
- Return type:
str
- classmethod validate_type(value, info)
Validate that the type channel
- classmethod parse_filters_string(value)
Parse string representation of filters into list of AppliedFilter objects
- classmethod validate_filters(value, info)
sort the filters by stage number and check for duplicates
- add_filter(applied_filter=None, name=None, applied=True, stage=None, comments=None)
Add a filter to the filter list.
- Parameters:
name (str) – Name of the filter.
applied (bool, optional) – Whether the filter has been applied, by default True.
stage (int | None, optional) – Stage of the filter in the processing chain, by default None.
- property filter_names: list[str]
List of filter names applied to the channel.
- Returns:
List of filter names.
- Return type:
list[str]
- remove_filter(name, reset_stages=True)
Remove a filter from the filter list.
- Parameters:
name (str) – Name of the filter to remove.
reset_stages (bool, optional) – Whether to reset the stages of the remaining filters, by default True.
- get_filter(name)
Get a filter from the filter list by name.
- Parameters:
name (str) – Name of the filter to get.
- Returns:
The filter with the given name, or None if not found.
- Return type:
AppliedFilter | None
- channel_response(filters_dict)
full channel response from a dictionary of filter objects
- property unit_object: mt_metadata.common.units.Unit
Some channels have a unit object that is used to convert between units. This is a property that returns the unit object for the channel. The unit object is created using the units attribute of the channel. The unit object is used to convert between units and to get the unit
- Returns:
BaseModel object with unit attributes
- Return type:
- from_dict(meta_dict, skip_none=False)
Fill attributes from a dictionary with backwards compatibility for legacy filter formats.
- Parameters:
meta_dict (dict) – Dictionary of attributes to set.
skip_none (bool, optional) – If True, skip attributes with None values, by default False.
- Raises:
MTSchemaError – If the input dictionary is not valid.
Notes
Supports backwards compatibility for three filter formats:
Legacy format (oldest): - Keys: ‘filter.applied’, ‘filter.name’ - Values: Lists of booleans and strings
Old format (intermediate): - Keys: ‘filtered.applied’, ‘filtered.name’ - Values: Lists of booleans and strings
New format (current): - Key: ‘filters’ - Value: List of AppliedFilter objects or dictionaries
All legacy formats are automatically converted to the new format using AppliedFilter objects. A warning is issued when legacy formats are detected.
- class mt_metadata.timeseries.Auxiliary(**data)
Bases:
mt_metadata.timeseries.ChannelAuxiliary channel class for storing auxiliary channel information.
- type: Annotated[str, Field(default='auxiliary', description='Data type for the channel, should be a descriptive word that a user can understand.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': 'auxiliary', 'type': 'string'})]
- class mt_metadata.timeseries.Electric(**data)
Bases:
mt_metadata.timeseries.ChannelBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- component: Annotated[str, Field(default='e_default', description='Component of the electric field.', alias=None, pattern='^[eE][a-zA-Z0-9_]*$', json_schema_extra={'units': None, 'required': True, 'examples': ['Ex']})]
- dipole_length: Annotated[float, Field(default=0.0, description='Length of the dipole as measured in a straight line from electrode to electrode.', alias=None, json_schema_extra={'units': 'meters', 'required': True, 'examples': ['55.25']})]
- positive: Annotated[mt_metadata.timeseries.Electrode, Field(default_factory=Electrode, description='Positive electrode.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['Electrode()']})]
- negative: Annotated[mt_metadata.timeseries.Electrode, Field(default_factory=Electrode, description='Negative electrode.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['Electrode()']})]
- contact_resistance: Annotated[mt_metadata.common.StartEndRange, Field(default_factory=StartEndRange, description='Contact resistance start and end values.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['StartEndRange()']})]
- ac: Annotated[mt_metadata.common.StartEndRange, Field(default_factory=StartEndRange, description='AC start and end values.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['StartEndRange()']})]
- dc: Annotated[mt_metadata.common.StartEndRange, Field(default_factory=StartEndRange, description='DC start and end values.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['StartEndRange()']})]
- type: Annotated[str, Field(default='electric', description='Data type for the channel, should be a descriptive word that a user can understand.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['electric']})]
- class mt_metadata.timeseries.Magnetic(**data)
Bases:
mt_metadata.timeseries.ChannelBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- component: Annotated[str, Field(default='h_default', description='Component of the magnetic field.', alias=None, pattern='^[hHbBrR][a-zA-Z0-9_]*$', json_schema_extra={'units': None, 'required': True, 'examples': ['hx']})]
- h_field_min: Annotated[mt_metadata.common.StartEndRange, Field(default_factory=StartEndRange, description='minimum of field strength at the beginning and end', alias=None, json_schema_extra={'units': 'nanotesla', 'required': True, 'examples': ['StartEndRange(start=0.01, end=0.02)']})]
- h_field_max: Annotated[mt_metadata.common.StartEndRange, Field(default_factory=StartEndRange, description='maximum of field strength at the beginning and end', alias=None, json_schema_extra={'units': 'nanotesla', 'required': True, 'examples': ['StartEndRange(start=0.1, end=2.0)']})]
- type: Annotated[str, Field(default='magnetic', description='Data type for the channel, should be a descriptive word that a user can understand.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['magnetic']})]
- class mt_metadata.timeseries.Run(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- channels_recorded_auxiliary: Annotated[list[str], Field(default_factory=list, description='List of auxiliary channels recorded', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['[T]']})]
- channels_recorded_electric: Annotated[list[str], Field(default_factory=list, description='List of electric channels recorded', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['[Ex , Ey]']})]
- channels_recorded_magnetic: Annotated[list[str], Field(default_factory=list, description='List of magnetic channels recorded', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['[Hx , Hy , Hz]']})]
- channels_recorded_all()
List of all channels recorded in the run.
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=Comment, description='Any comments on the run.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['cows chewed cables']})]
- data_type: Annotated[mt_metadata.common.DataTypeEnum, Field(default=DataTypeEnum.BBMT, description='Type of data recorded for this run.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['BBMT']})]
- id: Annotated[str, Field(default='', description='Run ID should be station name followed by a number or character. Characters should only be used if the run number is small, if the run number is high consider using digits with zeros. For example if you have 100 runs the run ID could be 001 or {station}001.', alias=None, pattern='^[a-zA-Z0-9_]*$', json_schema_extra={'units': None, 'required': True, 'examples': ['001']})]
- sample_rate: Annotated[float, Field(default=0.0, description='Digital sample rate for the run', alias=None, json_schema_extra={'units': 'samples per second', 'required': True, 'examples': ['100']})]
- acquired_by: Annotated[mt_metadata.common.AuthorPerson, Field(default_factory=AuthorPerson, description='Information about the group that collected the data.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Person()']})]
- metadata_by: Annotated[mt_metadata.common.AuthorPerson, Field(default_factory=AuthorPerson, description='Information about the group that collected the metadata.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Person()']})]
- provenance: Annotated[mt_metadata.common.Provenance, Field(default_factory=Provenance, description='Provenance information about the run.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Provenance()']})]
- time_period: Annotated[mt_metadata.common.TimePeriod, Field(default_factory=TimePeriod, description='Time period for the run.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ["TimePeriod(start='2020-01-01', end='2020-12-31')"]})]
- data_logger: Annotated[mt_metadata.timeseries.DataLogger, Field(default_factory=DataLogger, description='Data Logger information used to collect the run.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['DataLogger()']})]
- fdsn: Annotated[mt_metadata.common.Fdsn, Field(default_factory=Fdsn, description='FDSN information for the run.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Fdsn()']})]
- channels: Annotated[mt_metadata.common.list_dict.ListDict | list | dict | collections.OrderedDict, Field(default_factory=ListDict, description='ListDict of channel objects collected in this run.', alias=None, exclude=True, json_schema_extra={'units': None, 'required': False, 'examples': ['ListDict(Electric(), Magnetic(), Auxiliary())']})]
- classmethod validate_comments(value, info)
Validate that the value is a valid comment.
- classmethod validate_data_type(value, info)
Validate that the data_type is a string.
- classmethod validate_list_of_strings(value, info)
Validate that the value is a list of strings.
- validate_channels_recorded()
Validate that the value is a list of strings.
- classmethod validate_channels(value, info)
- merge(other, inplace=True)
Merge channels from another Run into this run.
Combines channels from two runs and updates the channels recorded lists and time period.
- Parameters:
other (Run) – Another Run object whose channels will be merged into this run.
inplace (bool, optional) – If True, update this run and update time period. If False, return a copy of the merged run (default is True).
- Returns:
If inplace is False, returns a copy of the merged Run. Otherwise None.
- Return type:
Run | None
- Raises:
TypeError – If other is not a Run object.
Examples
Merge runs in place:
>>> run1 = Run(id='001') >>> run1.add_channel(Electric(component='ex')) >>> run2 = Run(id='002') >>> run2.add_channel(Magnetic(component='hx')) >>> run1.merge(run2, inplace=True) >>> print(run1.channels_recorded_all) ['ex', 'hx']
Merge and return new run:
>>> merged_run = run1.merge(run2, inplace=False) >>> print(merged_run.channels_recorded_all) ['ex', 'hx']
See also
updateUpdate metadata from another run
- update(other, match=[])
Update attribute values from another Run object.
Copies non-None, non-default attribute values from another Run object to this one. Skips empty values like None, 0.0, [], empty strings, and default timestamps.
- Parameters:
other (Run) – Another Run object to copy attributes from.
match (list[str] | None, optional) – List of attribute names that must match between runs before updating. If any don’t match, raises ValueError. Typically used for ‘id’ to ensure runs are compatible (default is None).
- Raises:
ValueError – If any attributes in match list don’t have equal values.
TypeError – If other is not a compatible Run type.
Examples
Basic update:
>>> run1 = Run(id='001', sample_rate=256.0) >>> run2 = Run(id='001', sample_rate=0.0) >>> run2.acquired_by.author = 'J. Doe' >>> run1.update(run2) >>> print(run1.acquired_by.author) 'J. Doe' >>> print(run1.sample_rate) # Not updated (run2 has default 0.0) 256.0
Update with matching check:
>>> run1 = Run(id='001') >>> run2 = Run(id='002') >>> try: ... run1.update(run2, match=['id']) ... except ValueError as e: ... print("IDs don't match!") IDs don't match!
Notes
Channel metadata is also updated. For each channel in other, if the channel exists in this run, it’s updated; if not, it’s added.
Skipped values:
None
0.0
Empty lists []
Empty strings ‘’
Default timestamp ‘1980-01-01T00:00:00+00:00’
See also
mergeMerge channels from another run
- has_channel(component)
Check if a channel with the given component exists in the run.
- Parameters:
component (str) – Channel component name to search for (e.g., ‘ex’, ‘hy’).
- Returns:
True if channel exists, False otherwise.
- Return type:
bool
Examples
>>> run = Run(id='001') >>> run.add_channel(Electric(component='ex')) >>> print(run.has_channel('ex')) True >>> print(run.has_channel('ey')) False
See also
get_channelRetrieve a channel object
channel_indexGet the index of a channel
- channel_index(component)
Get the index of a channel in the channels_recorded_all list.
- Parameters:
component (str) – Channel component name to search for (e.g., ‘ex’, ‘hy’).
- Returns:
Index of the channel if found, None otherwise.
- Return type:
int | None
Examples
>>> run = Run(id='001') >>> run.add_channel(Electric(component='ex')) >>> run.add_channel(Electric(component='ey')) >>> run.add_channel(Magnetic(component='hx')) >>> print(run.channel_index('ey')) 1 >>> print(run.channel_index('hz')) None
Notes
Channels are sorted alphabetically in channels_recorded_all.
See also
has_channelCheck if channel exists
get_channelRetrieve channel object
- get_channel(component)
Retrieve a channel object by component name.
- Parameters:
component (str) – Channel component name to retrieve (e.g., ‘ex’, ‘hy’).
- Returns:
Channel object if found, None otherwise. Return type depends on the channel type.
- Return type:
Examples
>>> run = Run(id='001') >>> ex = Electric(component='ex', dipole_length=100.0) >>> run.add_channel(ex) >>> channel = run.get_channel('ex') >>> print(type(channel).__name__) 'Electric' >>> print(channel.dipole_length) 100.0 >>> print(run.get_channel('ey')) None
See also
has_channelCheck if channel exists
add_channelAdd a channel to the run
- add_channel(channel_obj, update=True)
Add or update a channel in the run.
If the channel already exists (matched by component), its metadata is updated. If it doesn’t exist, it’s added to the channels list. Can accept channel objects, dictionaries, or component strings.
- Parameters:
channel_obj (Electric | Magnetic | Auxiliary | dict | str) –
Channel to add. Can be:
Channel object (Electric, Magnetic, or Auxiliary)
Dictionary with channel attributes (must include ‘type’ or ‘component’)
String component name (e.g., ‘ex’, ‘hy’, ‘temp’)
If string, channel type is inferred:
Starts with ‘e’ → Electric
Starts with ‘h’ or ‘b’ or equals ‘magnetic’ → Magnetic
Otherwise → Auxiliary
update (bool, optional) – If True, update the run’s time period to include this channel’s time period. If False, don’t update time period (default is True).
Examples
Add channel objects:
>>> run = Run(id='001') >>> ex = Electric(component='ex', dipole_length=100.0) >>> run.add_channel(ex) >>> print(run.channels_recorded_electric) ['ex']
Add from string (infers type):
>>> run.add_channel('hy') >>> run.add_channel('temperature') >>> print(run.channels_recorded_magnetic) ['hy'] >>> print(run.channels_recorded_auxiliary) ['temperature']
Add from dictionary:
>>> channel_dict = { ... 'type': 'electric', ... 'component': 'ey', ... 'dipole_length': 95.0 ... } >>> run.add_channel(channel_dict)
Update existing channel:
>>> ex_updated = Electric(component='ex', dipole_length=105.0) >>> run.add_channel(ex_updated) # Updates existing 'ex' >>> print(run.get_channel('ex').dipole_length) 105.0
Add without updating time period:
>>> run.add_channel('hz', update=False)
Notes
This method automatically:
Updates channels_recorded lists
Updates run time period (if update=True)
Converts string/dict inputs to proper channel objects
Logs when updating existing channels
See also
remove_channelRemove a channel from the run
get_channelRetrieve a channel object
update_time_periodManually update time period
- remove_channel(channel_id)
Remove a channel from the run.
- Parameters:
channel_id (str) – Channel component name to remove (e.g., ‘ex’, ‘hy’).
Examples
>>> run = Run(id='001') >>> run.add_channel(Electric(component='ex')) >>> run.add_channel(Electric(component='ey')) >>> print(run.channels_recorded_electric) ['ex', 'ey'] >>> run.remove_channel('ex') >>> print(run.channels_recorded_electric) ['ey'] >>> run.remove_channel('ez') # Doesn't exist # Logs warning: Could not find ez to remove.
Notes
Automatically updates the channels_recorded lists after removal. Logs a warning if the channel is not found.
See also
add_channelAdd a channel to the run
has_channelCheck if channel exists
- update_channel_keys()
Update channel dictionary keys to match current component values.
Updates the keys in the channels ListDict to match current channel components. Useful when channel components have been modified after channels were added, ensuring channels can be accessed by their current component values.
- Returns:
Mapping of old keys to new keys showing what was changed.
- Return type:
dict[str, str]
Examples
Fix keys after modifying components:
>>> run = Run(id='001') >>> channel = Electric(component='') >>> run.add_channel(channel) >>> # Channel is stored with empty string key >>> channel.component = 'ex' >>> key_mapping = run.update_channel_keys() >>> print(key_mapping) {'': 'ex'} >>> # Now accessible as run.channels['ex'] >>> print(run.get_channel('ex').component) 'ex'
Multiple key updates:
>>> run = Run(id='001') >>> ch1 = Electric(component='e1') >>> ch2 = Magnetic(component='h1') >>> run.add_channel(ch1) >>> run.add_channel(ch2) >>> ch1.component = 'ex' >>> ch2.component = 'hx' >>> mapping = run.update_channel_keys() >>> print(mapping) {'e1': 'ex', 'h1': 'hx'}
Notes
This is typically only needed if you’ve directly modified channel component attributes after adding them to the run. Normal usage doesn’t require calling this method.
See also
add_channelAdd channels to the run
get_channelAccess channels by component
- property n_channels: int
Number of channels in the run.
- Returns:
Count of channels currently in the run.
- Return type:
int
Examples
>>> run = Run(id='001') >>> print(run.n_channels) 0 >>> run.add_channel('ex') >>> run.add_channel('hy') >>> print(run.n_channels) 2
- update_time_period()
Update run’s time period to encompass all channel time periods.
Examines all channels in the run and updates the run’s start and end times to include the earliest start and latest end from all channels. Ignores default timestamp ‘1980-01-01T00:00:00+00:00’.
Examples
>>> from mt_metadata.timeseries import Run, Electric >>> run = Run(id='001') >>> ex = Electric(component='ex') >>> ex.time_period.start = '2020-01-01T00:00:00+00:00' >>> ex.time_period.end = '2020-01-01T01:00:00+00:00' >>> run.add_channel(ex, update=False) >>> print(run.time_period.start) 1980-01-01T00:00:00+00:00 >>> run.update_time_period() >>> print(run.time_period.start) 2020-01-01T00:00:00+00:00
Multiple channels:
>>> ey = Electric(component='ey') >>> ey.time_period.start = '2020-01-01T00:30:00+00:00' >>> ey.time_period.end = '2020-01-01T02:00:00+00:00' >>> run.add_channel(ey, update=True) >>> print(run.time_period.start) # Uses earliest 2020-01-01T00:00:00+00:00 >>> print(run.time_period.end) # Uses latest 2020-01-01T02:00:00+00:00
Notes
Only updates if channels exist (n_channels > 0)
Ignores channels with default timestamp
Always expands time period, never shrinks it
Automatically called by add_channel() when update=True
See also
add_channelAdd channel and optionally update time period
- class mt_metadata.timeseries.Station(**data)
Bases:
mt_metadata.base.MetadataBaseBase 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.
- _skip_equals
Private attribute listing fields to skip in equality comparisons
- Type:
list[str]
- _fields
Private attribute caching field information
- Type:
dict[str, Any]
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
- channel_layout: Annotated[mt_metadata.common.ChannelLayoutEnum, Field(default=ChannelLayoutEnum.X, description='How the station channels were laid out.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['X']})]
- channels_recorded: Annotated[list[str], Field(default_factory=list, description='List of components recorded by the station. Should be a summary of all channels recorded. Dropped channels will be recorded in Run metadata.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['"[ Ex, Ey, Hx, Hy, Hz, T]"']})]
- comments: Annotated[mt_metadata.common.Comment, Field(default_factory=Comment, description='Any comments on the station.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['cows chewed cables']})]
- data_type: Annotated[mt_metadata.common.DataTypeEnum, Field(default='BBMT', description='Type of data recorded. If multiple types input as a comma separated list.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['BBMT']})]
- fdsn: Annotated[mt_metadata.common.Fdsn, Field(default_factory=Fdsn, description='FDSN information for the station.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Fdsn()']})]
- geographic_name: Annotated[str, Field(default='', description='Closest geographic name to the station, usually a city, but could be another common geographic location.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['Whitehorse, YK']})]
- id: Annotated[str, Field(default='', description='Station ID name. This should be an alpha numeric name that is typically 5-6 characters long. Commonly the project name in 2 or 3 letters and the station number.', alias=None, pattern='^[a-zA-Z0-9_-]*$', json_schema_extra={'units': None, 'required': True, 'examples': ['MT001']})]
- run_list: Annotated[list[str], Field(default_factory=list, description='List of runs recorded by the station. Should be a summary of all runs recorded.', alias=None, json_schema_extra={'units': None, 'required': True, 'examples': ['[ mt001a, mt001b, mt001c ]']})]
- location: Annotated[mt_metadata.common.StationLocation, Field(default_factory=StationLocation, description='Location of the station.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['StationLocation(latitude=60.0, longitude=-135.0)']})]
- orientation: Annotated[mt_metadata.common.Orientation, Field(default_factory=Orientation, description='Orientation of the station.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Orientation(north=0, east=0, vertical=1)']})]
- acquired_by: Annotated[mt_metadata.common.AuthorPerson, Field(default_factory=AuthorPerson, description='Group or person who acquired the data.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Person()']})]
- provenance: Annotated[mt_metadata.common.Provenance, Field(default_factory=Provenance, description='Provenance of the data.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ['Provenance()']})]
- time_period: Annotated[mt_metadata.common.TimePeriod, Field(default_factory=TimePeriod, description='Time period of the data.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ["TimePeriod(start='2020-01-01', end='2020-12-31')"]})]
- runs: Annotated[mt_metadata.common.list_dict.ListDict | list | dict | collections.OrderedDict | tuple, Field(default_factory=ListDict, description='List of runs recorded by the station.', alias=None, json_schema_extra={'units': None, 'required': False, 'examples': ["[Run(id='mt001a'), Run(id='mt001b'), Run(id='mt001c')]"]})]
- classmethod validate_comments(value, info)
- classmethod validate_list_of_strings(value, info)
Validate that the value is a list of strings.
- validate_runs_and_channels_recorded()
Validate that the value is a list of strings.
- validate_station_id()
Validate that the value is a list of strings.
- classmethod validate_runs(value, info)
- merge(other, inplace=False)
- property n_runs: int
Return the number of runs in the station.
- Returns:
number of runs in the station
- Return type:
int
- has_run(run_id)
Check to see if the run id already exists
- Parameters:
run_id (string) – run id verbatim
- Returns:
Tru if exists, False if not
- Return type:
boolean
- run_index(run_id)
Get the index of the run_id
- Parameters:
run_id (string) – run id verbatim
- Returns:
index of the run
- Return type:
integer
- update_channels_recorded()
Update the channels recorded lists based on the channels in the run.
- update_run_list()
Update the run list based on the runs in the station.
- update_time_period()
update time period from run information
- update_all()
Update the time period, channels recorded and run list.
- add_run(run_obj, update=True)
Add a run, if one of the same name exists overwrite it.
- Parameters:
run_obj (
mt_metadata.timeseries.Run) – run object to add
- get_run(run_id)
Get a
mt_metadata.timeseries.Runobject from the given id- Parameters:
run_id (string) – run id verbatim
- remove_run(run_id, update=True)
remove a run from the survey
- Parameters:
run_id (string) – run id verbatim
- update_run_keys()
Update the keys in the runs ListDict to match current run IDs.
This is useful when run IDs have been modified after runs were added to the station, ensuring that runs can be accessed by their current ID values.
- Returns:
mapping of old keys to new keys
- Return type:
dict
Example
>>> station = Station() >>> run = Run() >>> run.id = "" # empty ID initially >>> station.add_run(run) >>> run.id = "001" # update the ID >>> key_mapping = station.update_run_keys() >>> print(key_mapping) # {'': '001'} >>> # Now run can be accessed as station.runs['001']
- sort_runs_by_time(inplace=True, ascending=True)
return a list of runs sorted by start time in the order of ascending or descending.
- Parameters:
ascending (TYPE, optional) – DESCRIPTION, defaults to True
- Returns:
DESCRIPTION
- Return type:
TYPE
- class mt_metadata.timeseries.Experiment(**data)
Bases:
mt_metadata.base.MetadataBaseTop level of the metadata
- surveys: Annotated[mt_metadata.common.list_dict.ListDict | list | dict | collections.OrderedDict, Field(default_factory=ListDict, description='List of surveys in the experiment', title='List of Surveys', json_schema_extra={'required': False, 'units': None, 'examples': [{'id': 'survey_1'}, {'id': 'survey_2'}]})]
- merge(other)
Merge two Experiment objects
- property n_surveys: int
- classmethod validate_surveys(value)
set the survey list
- property survey_names: list[str]
Return names of surveys in experiment
- has_survey(survey_id)
Has survey id
- Parameters:
survey_id (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- survey_index(survey_id)
Get survey index
- Parameters:
survey_id (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- add_survey(survey_obj)
Add a survey, if has the same name update that object.
- Parameters:
survey_obj (:class:`mt_metadata.timeseries.Survey) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- get_survey(survey_id)
Get a survey from the survey id
- Parameters:
survey_id (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- remove_survey(survey_id, update=True)
Remove a survey from the experiment
- Parameters:
survey_id (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- to_dict(nested=False, required=True)
create a dictionary for the experiment object.
- Parameters:
nested (TYPE, optional) – DESCRIPTION, defaults to False
single (TYPE, optional) – DESCRIPTION, defaults to False
required (TYPE, optional) – DESCRIPTION, defaults to True
- Returns:
DESCRIPTION
- Return type:
TYPE
- from_dict(ex_dict, skip_none=True)
fill from an input dictionary
- Parameters:
ex_dict (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- to_json(fn=None, nested=False, indent=' ' * 4, required=True)
Write a json string from a given object, taking into account other class objects contained within the given object.
- Parameters:
nested ([ True | False ] , default is False) – make the returned json nested
- from_json(json_str, skip_none=True)
read in a json string and update attributes of an object
- Parameters:
json_str (string or
pathlib.Path) – json string or file path
- to_xml(fn=None, required=True, sort=True)
Write XML version of the experiment
- Parameters:
fn (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- from_xml(fn=None, element=None, sort=True, skip_none=True)
- Parameters:
fn (TYPE, optional) – DESCRIPTION, defaults to None
element (TYPE, optional) – DESCRIPTION, defaults to None
- Returns:
DESCRIPTION
- Return type:
TYPE
- to_pickle(fn=None)
Write a pickle version of the experiment
- Parameters:
fn (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- from_pickle(fn=None)
Read pickle version of experiment
- Parameters:
fn (TYPE) – DESCRIPTION
- Returns:
DESCRIPTION
- Return type:
TYPE
- sort(inplace=True)
sort surveys, stations, runs, channels alphabetically/numerically
- Parameters:
inplace (TYPE, optional) – DESCRIPTION, defaults to True
- Returns:
DESCRIPTION
- Return type:
TYPE