mtpy.core.transfer_function.z_analysis package
Submodules
mtpy.core.transfer_function.z_analysis.distortion module
mtpy/analysis/distortion.py
Contains functions for the determination of (compalvanic) distortion of impedance tensors. The methods used follow Bibby et al 2005. As it has been pointed out in that paper, there are various possibilities for constrainincomp the solution, esp. in the 2D case.
Here we just implement the ‘most basic’ variety for the calculation of the distortion tensor. Other methods can be implemented, but since the optimal assumptions and constraints depend on the application, the actual place for further functions is in an independent, personalised module.
Alcomporithm Details: Findincomp the distortion of a Z array. Usincomp the phase tensor so, Z arrays are transformed into PTs first), followincomp Bibby et al. 2005.
First, try to find periods that indicate 1D. From them determine D incl. the comp-factor by calculatiincomp a weicomphted mean. The comp is assumed in order to cater for the missincomp unknown in the system, it is here set to det(X)^0.5. After that is found, the function no_distortion from the Z module can be called to obtain the unperturbated recompional impedance tensor.
Second, if there are no 1D sections: Find the strike angle, then rotate the Z to the principal axis. In order to do that, use the rotate(-strike) method of the Z module. Then take the real part of the rotated Z. As in the 1D case, we need an assumption to compet rid of the (2) unknowns: set det(D) = P and det(D) = T, where P,T can be chosen. Common choice is to set one of P,T to an arbitrary value (e.comp. 1). Then check, for which values of the other parameter S^2 = T^2+4*P*X_12*X_21/det(X) > 0 holds.
@UofA, 2013 (LK)
Edited by JP, 2016
- mtpy.core.transfer_function.z_analysis.distortion.find_distortion(z_object, comp: str = 'det', only_2d: bool = False, clockwise: bool = True) tuple[ndarray, ndarray][source]
Find optimal distortion tensor from impedance tensor object.
Automatically determine the dimensionality over all frequencies, then find the appropriate distortion tensor D.
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
comp (str, optional) – Component for gain calculation (“det”, “01”, or “10”), by default “det”
only_2d (bool, optional) – If True, treat 1D as non-distorted (set to dimension 4), by default False
clockwise (bool, optional) – Rotation direction for strike angle, by default True
- Returns:
dis_avg (np.ndarray) – Average distortion tensor (2, 2)
dis_avg_error (np.ndarray) – Average distortion tensor error (2, 2)
Examples
>>> import mtpy.analysis.distortion as distortion >>> dis, dis_error = distortion.find_distortion(z_object, num_freq=12)
- mtpy.core.transfer_function.z_analysis.distortion.remove_distortion_from_z_object(z_object, distortion_tensor: ndarray, distortion_error_tensor: ndarray | None = None, logger=None) tuple[ndarray, ndarray][source]
Remove distortion D from an observed impedance tensor Z to obtain Z0.
The relationship is Z = D * Z0, where Z0 is the unperturbed impedance. Units should be in MT units of mV/km/nT.
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
distortion_tensor (np.ndarray) – Real distortion tensor with shape (2, 2)
distortion_error_tensor (np.ndarray or None, optional) – Real distortion tensor error with shape (2, 2), by default None
logger (logging.Logger or None, optional) – Logger for messages, by default None
- Returns:
z_corrected (np.ndarray) – Impedance tensor with distortion removed, shape (num_frequency, 2, 2)
z_corrected_error (np.ndarray) – Impedance tensor error after distortion is removed, shape (num_frequency, 2, 2)
- Raises:
ValueError – If distortion tensor has incorrect shape or is singular
Notes
Propagation of errors/uncertainties is included in the calculation.
mtpy.core.transfer_function.z_analysis.niblettbostick module
mtpy/mtpy/analysis/niblettbostick.py
Contains functions for the calculation of the Niblett-Bostick transformation of impedance tensors.
The methods follow:
Niblett
Bostick
Jones
RODRIGUEZ, F.J. ESPARZA, E. GOMEZ-TREVINO
Niblett-Bostick transformations are possible in 1D and 2D.
@UofA, 2013 (LK)
Updated 2022-09 JP
- mtpy.core.transfer_function.z_analysis.niblettbostick.calculate_depth_of_investigation(z_object) ndarray[source]
Determine depth-dependent Niblett-Bostick transformed impedance tensor.
Calculates Z_nb (depth dependent Niblett-Bostick transformed Z) from the 1D and 2D parts of an impedance tensor array Z.
The calculation follows 6 steps:
Determine the dimensionality of Z(T), discard all 3D parts
Rotate all Z(T) to TE/TM setup (T_parallel/T_ortho)
Transform every component individually by Niblett-Bostick
Collect the respective 2 components each for equal/similar depths
Interpret them as TE_nb/TM_nb
Set up Z_nb(depth)
If 1D layers occur between 2D layers, the strike angle is undefined. A linear interpolation of strike angle is used for these layers, with values varying between the angles of the bounding upper and lower 2D layers (linearly with respect to periods).
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
- Returns:
Structured array with fields: period, depth_xy, depth_yx, depth_det, depth_min, depth_max, resistivity_xy, resistivity_yx, resistivity_det, resistivity_min, resistivity_max
- Return type:
np.ndarray
Notes
No propagation of errors implemented yet.
Examples
>>> import mtpy.analysis.niblettbostick as nb >>> depth_array = nb.calculate_depth_of_investigation(z_object=z1) >>> # plot the results >>> import matplotlib.pyplot as plt >>> fig = plt.figure() >>> ax = fig.add_subplot(1,1,1) >>> ax.semilogy(depth_array['depth_min'], depth_array['period']) >>> ax.semilogy(depth_array['depth_max'], depth_array['period']) >>> plt.show()
- mtpy.core.transfer_function.z_analysis.niblettbostick.calculate_depth_sensitivity(depth: ndarray, period: ndarray, rho: float = 100) ndarray[source]
Compute sensitivity S(z, sigma, omega) = -kz*exp(-2*kz).
The result is independent of sigma and frequency.
- Parameters:
depth (np.ndarray) – Depth values in meters
period (np.ndarray) – Period values in seconds
rho (float, optional) – Resistivity in Ohm meters, by default 100
- Returns:
Sensitivity values
- Return type:
np.ndarray
- mtpy.core.transfer_function.z_analysis.niblettbostick.calculate_niblett_bostick_depth(resistivity: ndarray, period: ndarray) ndarray[source]
Use the Niblett-Bostick approximation for depth of penetration.
- Parameters:
resistivity (np.ndarray) – Resistivity values in Ohm meters
period (np.ndarray) – Period values in seconds
- Returns:
Depth of penetration in meters
- Return type:
np.ndarray
- mtpy.core.transfer_function.z_analysis.niblettbostick.calculate_niblett_bostick_resistivity_derivatives(resistivity: ndarray, period: ndarray) ndarray[source]
Convert resistivity to Niblett-Bostick resistivity using derivatives.
The conversion uses derivatives of log(resistivity) vs log(period). Bostick resistivity is only valid for -1 < m < 1, where m is the gradient.
- Parameters:
resistivity (np.ndarray) – Resistivity values in Ohm meters
period (np.ndarray) – Period values in seconds
- Returns:
Niblett-Bostick transformed resistivity in Ohm meters
- Return type:
np.ndarray
- mtpy.core.transfer_function.z_analysis.niblettbostick.calculate_niblett_bostick_resistivity_weidelt(resistivity: ndarray, phase: ndarray) ndarray[source]
Convert resistivity/phase to Niblett-Bostick resistivity using Weidelt approximation.
The conversion uses the simplified transformation without derivatives.
- Parameters:
resistivity (np.ndarray) – Resistivity values in Ohm meters
phase (np.ndarray) – Phase values in degrees
- Returns:
Niblett-Bostick transformed resistivity in Ohm meters
- Return type:
np.ndarray
mtpy.core.transfer_function.z_analysis.zinvariants module
Created on Wed May 08 09:40:42 2013
Originally written by Stephan Thiel in Matlab 2005 translated to Python by Lars Krieger
Revised by J. Peacock 2023 to fit with version 2.
- class mtpy.core.transfer_function.z_analysis.zinvariants.ZInvariants(z: ndarray | None = None)[source]
Bases:
objectCalculate invariants from Weaver et al. [2000, 2003].
At the moment it does not calculate the error for each invariant, only the strike.
- Parameters:
z (np.ndarray or None, optional) – Impedance tensor array with shape (nf, 2, 2), by default None
- z
Impedance tensor array
- Type:
np.ndarray or None
References
- property anisotropic_imag: ndarray | None
Anisotropic imaginary invariant (inv 4).
- property anisotropic_real: ndarray | None
Anisotropic real invariant (inv 3).
- property dimensionality: ndarray | None
Dimensionality parameter q.
- property electric_twist: ndarray | None
Electric twist invariant (inv 5).
- property normalizing_imag: ndarray | None
Normalizing imaginary invariant (inv 2).
- property normalizing_real: ndarray | None
Normalizing real invariant (inv 1).
- property phase_distortion: ndarray | None
Phase distortion invariant (inv 6).
- property strike: ndarray | None
Strike angle in degrees.
- property strike_error: ndarray | None
Strike angle error in degrees.
- property structure_3d: ndarray | None
3D structure invariant (inv 7).
Module contents
- class mtpy.core.transfer_function.z_analysis.ZInvariants(z: ndarray | None = None)[source]
Bases:
objectCalculate invariants from Weaver et al. [2000, 2003].
At the moment it does not calculate the error for each invariant, only the strike.
- Parameters:
z (np.ndarray or None, optional) – Impedance tensor array with shape (nf, 2, 2), by default None
- z
Impedance tensor array
- Type:
np.ndarray or None
References
[1] Weaver, J. T., Agarwal, A. K., Lilley, F. E. M., 2000, Characterization of the magnetotelluric tensor in terms of its invariants, Geophysical Journal International, 141, 321–336.
[2] Weaver, J. T., Agarwal, A. K., Lilley, F. E. M., 2003, The relationship between the magnetotelluric tensor invariants and the phase tensor of Caldwell, Bibby and Brown, presented at 3D Electromagnetics III, ASEG, paper 43.
[3] Lilley, F. E. M, 1998, Magnetotelluric tensor decomposition: 1: Theory for a basic procedure, Geophysics, 63, 1885–1897.
[4] Lilley, F. E. M, 1998, Magnetotelluric tensor decomposition: 2: Examples of a basic procedure, Geophysics, 63, 1898–1907.
[5] Szarka, L. and Menvielle, M., 1997, Analysis of rotational invariants of the magnetotelluric impedance tensor, Geophysical Journal International, 129, 133–142.
- property anisotropic_imag: ndarray | None
Anisotropic imaginary invariant (inv 4).
- property anisotropic_real: ndarray | None
Anisotropic real invariant (inv 3).
- property dimensionality: ndarray | None
Dimensionality parameter q.
- property electric_twist: ndarray | None
Electric twist invariant (inv 5).
- property normalizing_imag: ndarray | None
Normalizing imaginary invariant (inv 2).
- property normalizing_real: ndarray | None
Normalizing real invariant (inv 1).
- property phase_distortion: ndarray | None
Phase distortion invariant (inv 6).
- property strike: ndarray | None
Strike angle in degrees.
- property strike_error: ndarray | None
Strike angle error in degrees.
- property structure_3d: ndarray | None
3D structure invariant (inv 7).
- mtpy.core.transfer_function.z_analysis.calculate_depth_of_investigation(z_object) ndarray[source]
Determine depth-dependent Niblett-Bostick transformed impedance tensor.
Calculates Z_nb (depth dependent Niblett-Bostick transformed Z) from the 1D and 2D parts of an impedance tensor array Z.
The calculation follows 6 steps:
Determine the dimensionality of Z(T), discard all 3D parts
Rotate all Z(T) to TE/TM setup (T_parallel/T_ortho)
Transform every component individually by Niblett-Bostick
Collect the respective 2 components each for equal/similar depths
Interpret them as TE_nb/TM_nb
Set up Z_nb(depth)
If 1D layers occur between 2D layers, the strike angle is undefined. A linear interpolation of strike angle is used for these layers, with values varying between the angles of the bounding upper and lower 2D layers (linearly with respect to periods).
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
- Returns:
Structured array with fields: period, depth_xy, depth_yx, depth_det, depth_min, depth_max, resistivity_xy, resistivity_yx, resistivity_det, resistivity_min, resistivity_max
- Return type:
np.ndarray
Notes
No propagation of errors implemented yet.
Examples
>>> import mtpy.analysis.niblettbostick as nb >>> depth_array = nb.calculate_depth_of_investigation(z_object=z1) >>> # plot the results >>> import matplotlib.pyplot as plt >>> fig = plt.figure() >>> ax = fig.add_subplot(1,1,1) >>> ax.semilogy(depth_array['depth_min'], depth_array['period']) >>> ax.semilogy(depth_array['depth_max'], depth_array['period']) >>> plt.show()
- mtpy.core.transfer_function.z_analysis.find_distortion(z_object, comp: str = 'det', only_2d: bool = False, clockwise: bool = True) tuple[ndarray, ndarray][source]
Find optimal distortion tensor from impedance tensor object.
Automatically determine the dimensionality over all frequencies, then find the appropriate distortion tensor D.
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
comp (str, optional) – Component for gain calculation (“det”, “01”, or “10”), by default “det”
only_2d (bool, optional) – If True, treat 1D as non-distorted (set to dimension 4), by default False
clockwise (bool, optional) – Rotation direction for strike angle, by default True
- Returns:
dis_avg (np.ndarray) – Average distortion tensor (2, 2)
dis_avg_error (np.ndarray) – Average distortion tensor error (2, 2)
Examples
>>> import mtpy.analysis.distortion as distortion >>> dis, dis_error = distortion.find_distortion(z_object, num_freq=12)
- mtpy.core.transfer_function.z_analysis.remove_distortion_from_z_object(z_object, distortion_tensor: ndarray, distortion_error_tensor: ndarray | None = None, logger=None) tuple[ndarray, ndarray][source]
Remove distortion D from an observed impedance tensor Z to obtain Z0.
The relationship is Z = D * Z0, where Z0 is the unperturbed impedance. Units should be in MT units of mV/km/nT.
- Parameters:
z_object (mtpy.core.transfer_function.z.Z) – Impedance tensor object
distortion_tensor (np.ndarray) – Real distortion tensor with shape (2, 2)
distortion_error_tensor (np.ndarray or None, optional) – Real distortion tensor error with shape (2, 2), by default None
logger (logging.Logger or None, optional) – Logger for messages, by default None
- Returns:
z_corrected (np.ndarray) – Impedance tensor with distortion removed, shape (num_frequency, 2, 2)
z_corrected_error (np.ndarray) – Impedance tensor error after distortion is removed, shape (num_frequency, 2, 2)
- Raises:
ValueError – If distortion tensor has incorrect shape or is singular
Notes
Propagation of errors/uncertainties is included in the calculation.