2.7.6.1. pycsamt.airborne.afmag#
AFMAG-family scientific adapter contracts.
The package separates historical comparator AFMAG from modern tensor AFMAG/AirMt instead of collapsing distinct response families into one schema. No proprietary native delivery parser is assumed.
- exception pycsamt.airborne.afmag.AFMAGValidationError
Bases:
ValueErrorRaised when decoded AFMAG scientific arrays are inconsistent.
- pycsamt.airborne.afmag.register_afmag_datatypes()
Register AFMAG derived response definitions idempotently.
The tensor response itself reuses the existing EMTF
TIinterstation magnetic transfer-function definition and therefore is not re-registered.- Returns:
(AFMAG_TILT_DEFINITION, AFMAG_AP_DEFINITION), each either newly registered or the already-registered definition sharing its tag; seeensure_emtf_datatype_registered().- Return type:
- Raises:
ValueError – If either definition’s tag or code is already registered under a materially different definition.
- class pycsamt.airborne.afmag.OriginalAFMAGSystemSpec(historical_frequency_band_hz=(1.0, 20000.0), typical_frequencies_hz=(150.0, 510.0), coil_count=2, coil_tilt_deg=45.0, coil_separation_deg=45.0, digital_recording=False, attrs=<factory>)
Bases:
CoreObjectDescriptive characteristics of the historical comparator AFMAG.
These values describe the original airborne implementation and are not parser constraints. Historical systems reported a comparator deflection proportional to the polarization-plane tilt rather than a digital tensor; see
AFMAGValidationErrorandbuild_original_afmag_emtf()for how that scalar response is built.- Parameters:
historical_frequency_band_hz ((float, float), optional) – Published historical operating band in Hz,
(low, high)with0 < low < high.typical_frequencies_hz (tuple of float, optional) – Typical discrete operating frequencies in Hz historically used by comparator instruments (non-empty, finite, positive).
coil_count (int, default 2) – Fixed at 2: the original comparator design used two crossed coils.
coil_tilt_deg (float, optional) – Published nominal coil tilt angle in degrees.
coil_separation_deg (float, optional) – Published nominal angular separation between the two coils in degrees.
digital_recording (bool, default False) – Whether the archival record was digitized (
True) or is a purely analogue comparator deflection (False).attrs (dict, optional) – Free-form extension metadata.
- Raises:
ValueError – If historical_frequency_band_hz is not finite and correctly ordered, if typical_frequencies_hz is empty or not all finite/positive, if coil_count is not
2, or if coil_tilt_deg/coil_separation_deg is not finite/positive.
- coil_count: int = 2
- coil_tilt_deg: float = 45.0
- coil_separation_deg: float = 45.0
- digital_recording: bool = False
- validate()
Normalize and range-check every descriptive field in place.
- Return type:
None
- to_instrument_meta(*, serial=None, software_version='')
Return reusable instrument metadata for historical AFMAG.
Only a
magnetic_sensoris populated –electric_sensorstaysNone, since original comparator AFMAG has no electric channel.- Parameters:
- Return type:
- class pycsamt.airborne.afmag.AirMtSystemSpec(practical_frequency_range_hz=(20.0, 800.0), typical_frequency_count=(5, 6), time_series_sampling_rate_hz=2000.0, input_channels=('Hx', 'Hy'), output_channels=('Hx', 'Hy', 'Hz'), reference_channels=('Hx', 'Hy', 'Hz'), attrs=<factory>)
Bases:
CoreObjectPublished characteristics of the tensor AFMAG/AirMt generation.
- Parameters:
practical_frequency_range_hz ((float, float), optional) – Published practical frequency band in Hz,
(low, high)with0 < low < high. Seepractical_frequency_mask().typical_frequency_count ((int, int), optional) – Typical minimum/maximum count of processed frequency windows,
(low, high)with0 < low <= high.time_series_sampling_rate_hz (float, optional) – Published raw time-series sampling rate in Hz.
input_channels ((str, str), default ("Hx", "Hy")) – Fixed transfer-function input channels; must equal
("Hx", "Hy").output_channels ((str, str, str), default ("Hx", "Hy", "Hz")) – Fixed airborne transfer-function output channels; must equal
("Hx", "Hy", "Hz").reference_channels ((str, str, str), default ("Hx", "Hy", "Hz")) – Fixed channels measured at the fixed ground reference station; must equal
("Hx", "Hy", "Hz").attrs (dict, optional) – Free-form extension metadata.
- Raises:
ValueError – If practical_frequency_range_hz is not finite and correctly ordered, if typical_frequency_count is not a valid
0 < low <= highpair, if time_series_sampling_rate_hz is not finite/positive, or if input_channels/output_channels/ reference_channels differs from its fixed value.
- time_series_sampling_rate_hz: float = 2000.0
- validate()
Normalize and range-check every descriptive field in place.
- Return type:
None
- practical_frequency_mask(frequency)
Return a diagnostic mask for the descriptive frequency band.
- to_instrument_meta(*, serial=None, software_version='')
Return reusable instrument metadata for tensor AFMAG/AirMt.
Only a
magnetic_sensoris populated –electric_sensorstaysNone, since AirMt’s interstation transfer function has no electric channel.- Parameters:
- Return type:
- class pycsamt.airborne.afmag.AFMAGReferenceStation(station_id=None, site=None, measured_channels=('Hx', 'Hy', 'Hz'), transfer_input_channels=('Hx', 'Hy'), attrs=<factory>)
Bases:
CoreObjectFixed magnetic reference station for tensor AFMAG/AirMt processing.
Passed to
build_airmt_emtf()to populateprocessing’s remote-reference metadata; see_processing_for_reference().- Parameters:
station_id (str, optional) – Explicit reference-station identifier. Falls back to
site.preferred_namethroughpreferred_idwhen omitted; seenormalize_optional_identifier().site (SiteMeta, optional) – Reference-station location/identity metadata.
measured_channels ((str, str, str), default ("Hx", "Hy", "Hz")) – Fixed channels physically measured at the reference station; must equal
("Hx", "Hy", "Hz").transfer_input_channels ((str, str), default ("Hx", "Hy")) – Fixed subset of measured_channels used as the AirMt transfer function’s input; must equal
("Hx", "Hy").attrs (dict, optional) – Free-form extension metadata.
- Raises:
ValueError – If measured_channels differs from
("Hx", "Hy", "Hz")or transfer_input_channels differs from("Hx", "Hy").
- validate()
Normalize the identifier/channels and type-check
site.- Return type:
None
- pycsamt.airborne.afmag.compute_airmt_amplification_parameter(tensor, *, zero_policy='nan')
Compute the AirMt rotation-invariant complex amplification parameter.
For the two column vectors
T1andT2of a 3 x 2 magnetic transfer function, the implemented patent formulation is:Kvec = T1 x T2 AP = Kvec . Re(Kvec) / |Re(Kvec)|
- Parameters:
tensor (array-like) – One
(3, 2)or(3, 3)matrix, or a family with those trailing dimensions. The patent parameter uses the first two column vectors in either case.zero_policy ({"nan", "raise"}) – Behavior when
|Re(Kvec)|is zero. Such a sample has no defined projection direction for this parameter.
- Returns:
Complex AP with shape equal to the leading tensor dimensions.
- Return type:
- pycsamt.airborne.afmag.validate_airmt_transfer_function(tf)
Validate and return an AirMt 3 x 2 interstation magnetic TF.
- Parameters:
tf (TransferFunction) – Transfer function to validate in place.
- Returns:
tf, unchanged, for convenient chaining after
add_transfer_function().- Return type:
- Raises:
TypeError – If tf is not a
TransferFunction.AFMAGValidationError – If tf does not use the standard EMTF interstation
TI/interstation_transfer_functionsdatatype withHx/Hyinputs,Hx/Hy/Hzoutputs, and matrix shape(3, 2).
- pycsamt.airborne.afmag.validate_original_afmag_tilt(tf)
Validate and return an original AFMAG scalar tilt response.
- Parameters:
tf (TransferFunction) – Transfer function to validate in place.
- Returns:
tf, unchanged, for convenient chaining after
add_transfer_function().- Return type:
- Raises:
TypeError – If tf is not a
TransferFunction.AFMAGValidationError – If tf does not use the
afmag_tiltdatatype, is not scalar (no input/output channels, matrix shape(1, 1)), or carries a non-zero imaginary component.
- pycsamt.airborne.afmag.build_airmt_emtf(tensor, *, frequency=None, periods=None, units='[]', variance=None, inverse_signal_covariance=None, residual_covariance=None, include_amplification_parameter=True, amplification_zero_policy='nan', product_id=None, description=None, reference_station=None, system_spec=None, site=None, orientation=None, processing=None, attrs=None)
Build one sample-level tensor AFMAG/AirMt
EMTFresponse.- Parameters:
tensor (array-like) – Complex interstation magnetic transfer function with shape
(nf, 3, 2), or one(3, 2)matrix for a single frequency.frequency (array-like, optional) – Exactly one positive frequency or period vector must be supplied.
periods (array-like, optional) – Exactly one positive frequency or period vector must be supplied.
variance (array-like, optional) – Component variance with shape
(nf, 3, 2).inverse_signal_covariance (array-like, optional) – Input covariance factor
Swith shape(nf, 2, 2).residual_covariance (array-like, optional) – Output residual covariance
Nwith shape(nf, 3, 3).include_amplification_parameter (bool, default True) – Whether to also attach the derived
airmt_amplification_parametertransfer function; seecompute_airmt_amplification_parameter().amplification_zero_policy ({"nan", "raise"}, default "nan") – Forwarded to
compute_airmt_amplification_parameter().reference_station (AFMAGReferenceStation, optional) – Fixed ground reference metadata; folded into
EMTF.processingandEMTF.attrs["afmag"](see_processing_for_reference()).system_spec (AirMtSystemSpec, optional) – System-description metadata; defaults to published nominal values.
units (str | None)
product_id (str | None)
description (str | None)
site (SiteMeta | None)
orientation (OrientationMeta | None)
processing (ProcessingMeta | None)
- Returns:
Document carrying the
interstation_transfer_functions(TI) transfer function and, unless disabled, the derived amplification parameter.- Return type:
- Raises:
AFMAGValidationError – If tensor, frequency/periods, or any statistical estimate does not match its expected shape.
TypeError – If system_spec, reference_station, site, or orientation has the wrong type.
- pycsamt.airborne.afmag.build_airmt_record(sample_id, tensor, *, frequency=None, periods=None, fields=None, quality=None, record_attrs=None, **emtf_kwargs)
Build one airborne record from decoded tensor AFMAG/AirMt data.
- Parameters:
sample_id (str) – Navigation sample identifier for the new record.
tensor (array-like) – Forwarded to
build_airmt_emtf().frequency (array-like, optional) – Exactly one must be supplied; forwarded to
build_airmt_emtf().periods (array-like, optional) – Exactly one must be supplied; forwarded to
build_airmt_emtf().fields (dict, optional) – Forwarded to
AirborneEMRecord.quality (dict, optional) – Forwarded to
AirborneEMRecord.record_attrs (dict, optional) – Forwarded to
AirborneEMRecord.**emtf_kwargs – Forwarded to
build_airmt_emtf().
- Returns:
The record, with its EMTF
product_iddefaulted tostr(sample_id)unless overridden inemtf_kwargs.- Return type:
- pycsamt.airborne.afmag.build_airmt_line(line_id, navigation, tensor, *, frequency, record_mask=None, variance=None, inverse_signal_covariance=None, residual_covariance=None, units='[]', include_amplification_parameter=True, reference_station=None, system_spec=None, orientation=None, attrs=None)
Build one tensor-AFMAG/AirMt flight line from decoded arrays.
- Parameters:
line_id (str) – Flight-line identifier.
navigation (NavigationTrack) – Sample-aligned navigation defining the line’s sample axis.
tensor (array-like) – Line-batched interstation tensor. For
n_samples == 1, a single(3, 2)matrix or one(nf, 3, 2)stack is also accepted (n_frequencyis not known in advance, unlikenormalize_sample_axis_array()’s contract); forn_samples > 1, the canonical(samples, nf, 3, 2)shape is required directly.frequency (array-like) – Either one shared
(nf,)vector or a per-sample(n_samples, nf)grid; see_line_frequency_rows().record_mask (array-like of bool, optional) – Marks which navigation samples get an attached record;
Nonemeans every sample does.variance (Any | None)
inverse_signal_covariance (Any | None)
residual_covariance (Any | None)
array-like – Per-sample statistical estimates, each shaped
(n_samples, nf, *tail); forwarded per sample tobuild_airmt_record().optional – Per-sample statistical estimates, each shaped
(n_samples, nf, *tail); forwarded per sample tobuild_airmt_record().include_amplification_parameter (bool, default True) – Forwarded to
build_airmt_emtf()for every sample.units (optional) – Forwarded to
build_airmt_emtf()for every sample.reference_station (optional) – Forwarded to
build_airmt_emtf()for every sample.system_spec (optional) – Forwarded to
build_airmt_emtf()for every sample.orientation (optional) – Forwarded to
build_airmt_emtf()for every sample.attrs (dict, optional) – Line-level extension metadata;
"technology"is set to"AirMt"here.
- Returns:
The line, with one record per sample where
record_mask(or its default) isTrue.- Return type:
- Raises:
TypeError – If navigation is not a
NavigationTrack.AFMAGValidationError – If tensor, frequency, record_mask, or any statistical estimate does not match its expected shape.
- pycsamt.airborne.afmag.build_airmt_dataset(name, lines, *, survey=None, system_spec=None, instrument_serial=None, attrs=None)
Build a common airborne dataset for tensor AFMAG/AirMt lines.
- Parameters:
name (str) – Dataset/survey name.
lines (iterable of AirborneEMLine) – Lines to attach, typically previously built by
build_airmt_line().survey (SurveyMeta, optional) – Survey-level metadata; defaults to
SurveyMeta(name=name, method="AEM").system_spec (AirMtSystemSpec, optional) – Used to build the dataset’s
instrumentmetadata; defaults to published nominal values.instrument_serial (str, optional) – Forwarded to
AirMtSystemSpec.to_instrument_meta().attrs (dict, optional) – Dataset-level extension metadata;
"technology"is set to"AirMt"here.
- Returns:
The dataset, with every line attached.
- Return type:
- Raises:
TypeError – If system_spec has the wrong type, or an entry of lines is not an
AirborneEMLine(this is enforced byAirborneEMDatasetconstruction, unlikebuild_ztem_dataset(), which checks explicitly beforehand and additionally rejects a line tagged with a conflicting technology; this function does not perform that second, stricter check).
- pycsamt.airborne.afmag.build_original_afmag_emtf(tilt, *, frequency=None, periods=None, response_kind='tilt_angle', units=None, variance=None, product_id=None, description=None, system_spec=None, site=None, orientation=None, attrs=None)
Build one historical comparator-AFMAG scalar tilt response.
response_kind='tilt_angle'represents a calibrated tilt angle and defaults to degrees.'comparator_deflection'preserves an archival instrument deflection without pretending it is an angle; units should then be supplied when known.- Parameters:
tilt (array-like) – Real-valued tilt/deflection response, scalar or shape
(nf,).frequency (array-like, optional) – Exactly one positive frequency or period vector must be supplied.
periods (array-like, optional) – Exactly one positive frequency or period vector must be supplied.
response_kind (str, default "tilt_angle") – Either
"tilt_angle"(a calibrated angle, defaulting to degrees) or"comparator_deflection"(a raw archival instrument deflection with no implied angular unit).variance (array-like, optional) – Real-valued response variance, scalar or shape
(nf,)/(nf, 1, 1).system_spec (OriginalAFMAGSystemSpec, optional) – System-description metadata; defaults to published nominal values.
units (str | None)
product_id (str | None)
description (str | None)
site (SiteMeta | None)
orientation (OrientationMeta | None)
- Returns:
Document carrying the
afmag_tilttransfer function.- Return type:
- Raises:
AFMAGValidationError – If tilt, frequency/periods, or variance does not match its expected shape.
ValueError – If response_kind is not a recognized value.
TypeError – If system_spec, site, or orientation has the wrong type.
- pycsamt.airborne.afmag.build_original_afmag_record(sample_id, tilt, *, frequency=None, periods=None, fields=None, quality=None, record_attrs=None, **emtf_kwargs)
Build one record from a historical AFMAG tilt response.
- Parameters:
sample_id (str) – Navigation sample identifier for the new record.
tilt (array-like) – Forwarded to
build_original_afmag_emtf().frequency (array-like, optional) – Exactly one must be supplied; forwarded to
build_original_afmag_emtf().periods (array-like, optional) – Exactly one must be supplied; forwarded to
build_original_afmag_emtf().fields (dict, optional) – Forwarded to
AirborneEMRecord.quality (dict, optional) – Forwarded to
AirborneEMRecord.record_attrs (dict, optional) – Forwarded to
AirborneEMRecord.**emtf_kwargs – Forwarded to
build_original_afmag_emtf().
- Returns:
The record, with its EMTF
product_iddefaulted tostr(sample_id)unless overridden inemtf_kwargs.- Return type:
- pycsamt.airborne.afmag.build_original_afmag_line(line_id, navigation, tilt, *, frequency, record_mask=None, response_kind='tilt_angle', units=None, variance=None, system_spec=None, orientation=None, attrs=None)
Build one historical comparator-AFMAG flight line.
- Parameters:
line_id (str) – Flight-line identifier.
navigation (NavigationTrack) – Sample-aligned navigation defining the line’s sample axis.
tilt (array-like) – Line-batched real tilt/deflection response, shape
(n_samples, nf)(or unbatched whenn_samples == 1).frequency (array-like) – Either one shared
(nf,)vector or a per-sample(n_samples, nf)grid; see_line_frequency_rows().record_mask (array-like of bool, optional) – Marks which navigation samples get an attached record;
Nonemeans every sample does.response_kind (optional) – Forwarded to
build_original_afmag_emtf()for every sample.units (optional) – Forwarded to
build_original_afmag_emtf()for every sample.variance (array-like, optional) – Per-sample response variance, shape
(n_samples, nf).system_spec (optional) – Forwarded to
build_original_afmag_emtf()for every sample.orientation (optional) – Forwarded to
build_original_afmag_emtf()for every sample.attrs (dict, optional) – Line-level extension metadata;
"technology"is set to"AFMAG"here.
- Returns:
The line, with one record per sample where
record_mask(or its default) isTrue.- Return type:
- Raises:
TypeError – If navigation is not a
NavigationTrack.AFMAGValidationError – If tilt, frequency, record_mask, or variance does not match its expected shape.
- pycsamt.airborne.afmag.build_original_afmag_dataset(name, lines, *, survey=None, system_spec=None, instrument_serial=None, attrs=None)
Build a common airborne dataset for original AFMAG lines.
- Parameters:
name (str) – Dataset/survey name.
lines (iterable of AirborneEMLine) – Lines to attach, typically previously built by
build_original_afmag_line().survey (SurveyMeta, optional) – Survey-level metadata; defaults to
SurveyMeta(name=name, method="AEM").system_spec (OriginalAFMAGSystemSpec, optional) – Used to build the dataset’s
instrumentmetadata; defaults to published nominal values.instrument_serial (str, optional) – Forwarded to
OriginalAFMAGSystemSpec.to_instrument_meta().attrs (dict, optional) – Dataset-level extension metadata;
"technology"is set to"AFMAG"here.
- Returns:
The dataset, with every line attached.
- Return type:
- Raises:
TypeError – If system_spec has the wrong type, or an entry of lines is not an
AirborneEMLine; seebuild_airmt_dataset()for how this differs from the ZTEM/MobileMT dataset builders.