pycsamt.emtools.legacy#
- pycsamt.emtools.legacy.check_em_kind(objs, /)#
Validate a collection of EM objects and return their common kind.
Ensures that all elements in
objsare instances of eitherEdiorZ, but not a mix of both. Returns the common kind as"EDI"or"Z". Raises if the collection is empty, contains non-EM objects, or mixes kinds.- Parameters:
objs (iterable) – Iterable of objects expected to be all
Edior allZ. Strings and bytes are not valid inputs.- Returns:
"EDI"if all objects are EDI instances, else"Z"if all are Z instances.- Return type:
- Raises:
TypeError – If
objsis not an iterable, or is a string/bytes, or is empty.EMError – If an element is neither
EdinorZ, or if the iterable mixesEdiandZ.
Notes
Uses
is_instance_extended()to be robust to class reloads and alternate import paths.Examples
>>> from pycsamt.utils.em import check_em_kind >>> # assuming `eds` is a list of Edi instances >>> check_em_kind(eds) 'EDI' >>> # assuming `zs` is a list of Z instances >>> check_em_kind(zs) 'Z'
- pycsamt.emtools.legacy.extract_z_list(objs, /)#
Return a list of
Zobjects from EDI or Z inputs.If
objsis a collection ofEdi, each element’s.Zattribute is extracted. Ifobjsis already a collection ofZ, it is returned as a plain list.- Parameters:
objs (iterable) – Iterable of EM objects. Must be all
Edior allZ. Seecheck_em_kind().- Returns:
List of
Zinstances.- Return type:
- Raises:
TypeError – If
objsis not an iterable or is empty.EMError – If
objsmixesEdiandZ, contains non-EM objects, or anEdiis missing the.Zattribute.
Notes
Uses
check_em_kind()to validate homogeneity.Examples
>>> zs = extract_z_list(list_of_edi) # from EDI inputs >>> zs = extract_z_list(list_of_z) # already Z
- pycsamt.emtools.legacy.parse_tensor(out='resxy', *, tensor=None, component=None, kind='complex', **kws)#
Parse and validate a tensor request, returning name and component.
This helper normalizes shorthand like
'resxy'or explicit pairs liketensor='z', component='xy'and validates the desired numeric kind (e.g., complex, real, imag, modulus).- Parameters:
out (str, default='resxy') – Compact token specifying the tensor and component, e.g.
'resxy','zxy','phaseyx', or a frequency request such as'freq'. When bothtensorandcomponentare given, they overrideout.tensor (str, optional) – Tensor name or alias. Accepted values include:
'z','tensor','res','rho','rhoa','phase','phs','freq','frequency'.component (str, optional) – EM component among
'xx','xy','yx','yy'. Required for'z','resistivity'and'phase'.kind ({'complex','real','imag','modulus'}, default='complex') – Numeric form of the tensor to be later extracted. Aliases are accepted, e.g.
're'``→’real’, ``'im'``→’imag’, ``'abs'/'mod'``→’modulus’, ``'reel'``→’real’``.**kws – Extra keywords ignored here. Kept for API symmetry with callers that also manage frequency expansion.
- Returns:
(name, comp) – Normalized tensor name and its component. The
nameis one of'z','resistivity','phase','_freq', or includes the'_err'suffix for error arrays where applicable.compis'xx','xy','yx','yy'orNonefor frequency.- Return type:
- Raises:
EMError – If only one of
tensororcomponentis provided.ValueError – If the parsed tokens are invalid, the component is missing for a tensor that requires it, or
kindis unknown.
Examples
>>> parse_tensor('zxy') ('z', 'xy') >>> parse_tensor(tensor='res', component='yx') ('resistivity', 'yx') >>> parse_tensor('freq') ('_freq', None) >>> parse_tensor('resx') Traceback (most recent call last): ... ValueError: 'Resistivity' component is missing...
- pycsamt.emtools.legacy.compute_qc(z_or_edis_obj_list, /, tol=0.5, *, interpolate_freq=False, return_freq=False, tensor='res', return_data=False, to_log10=False, return_qco=False)#
Assess data quality across a collection of EDI/Z objects.
Computes a global completeness ratio \(1 - \#NaN / (N_{freq} N_{sta})\) from a 2-D tensor (freq × station). Frequencies whose per-row missing-data fraction exceeds
tolare dropped. Optionally interpolate the retained frequencies and/or return a structured summary object.- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Homogeneous collection of EM objects.
tol (float, default=0.5) – Tolerance threshold in
[0, 1]. A frequency row is considered invalid and dropped when its fraction of missing values exceedstol.interpolate_freq (bool, default=False) – If
True, interpolate the retained frequencies on a log-spaced grid spanning[min, max]with the same count.return_freq (bool, default=False) – If
True, return the retained (possibly interpolated) frequency vector.tensor ({'z','res','rho','rhoa','phase','phs'}, default='res') – Tensor family used for QC. The function first attempts the TE component (
'xy'); on failure, it falls back to TM ('yx').return_data (bool, default=False) – If
True, also return the subset of the tensor data corresponding to retained frequencies.to_log10 (bool, default=False) – If
True, returnlog10of the retained frequencies. Applied after interpolation ifinterpolate_freqis set.return_qco (bool, default=False) –
If
True, return aBunchwith the following attributes:rate_: global completeness ratiocomponent_: selected component,'xy'or'yx'mode_: EM mode,'TE'or'TM'freqs_: retained (optionally interpolated) frequenciesinvalid_freqs_: frequencies dropped by the QCdata_: tensor data at retained frequencies
Setting this flag forces
return_freq=Trueandreturn_data=True.
- Returns:
Depending on the flags.
rateis in[0, 1].- Return type:
Notes
The 2-D tensor has shape
(n_freq, n_stations). The per-row missing-data fraction isnan_count / n_stations.Examples
>>> rate, = compute_qc(data) >>> rate, freqs = compute_qc(data, return_freq=True) >>> rep = compute_qc(data, return_qco=True) >>> rep.rate_, rep.component_, rep.freqs_.shape (0.75, 'xy', (56,))
- pycsamt.emtools.legacy.full_freq(z_or_edis_obj_list, /, to_log10=False)#
Return the reference (clean) frequency grid for a collection.
The full frequency grid is taken from the site that contains the largest number of frequency samples (i.e., the most complete set). This is commonly used as the survey reference grid to which per-site tensors are aligned.
- Parameters:
- Returns:
The reference frequency vector.
- Return type:
- Raises:
TypeError – If the input is empty or not iterable.
EMError – If the collection mixes Edi and Z, or any element is missing a frequency attribute.
ValueError – If
to_log10=Trueand any frequency is non-positive.
Notes
For each object, the function looks for
.Z._freq/.Z.freq(whenEdi) or._freq/.freq(whenZ), using the first available attribute.Examples
>>> f = full_freq(edi_data) >>> f.shape (56,) >>> flog = full_freq(edi_data, to_log10=True)
- pycsamt.emtools.legacy.tensor2d(z_or_edis_obj_list, /, tensor='z', component='xy', kind='modulus', return_freqs=False, freqs=None, **kws)#
Build a 2-D matrix (freq × station) from a tensor collection.
Converts a collection of
EdiorZobjects into a 2-D array where rows are frequencies and columns are stations. Missing per-site frequencies are filled withNaN(no interpolation).- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Collection of EM objects. All items must be
Edior allZ.tensor (str, default='z') – Tensor name or alias. Examples include
'z','res'/'rho'/'rhoa','phase'/'phs'. Error arrays are supported (e.g.,'resistivity_err').component ({'xx','xy','yx','yy'}, default='xy') – Component to extract for non-frequency tensors.
kind ({'modulus','real','imag','complex'}, default='modulus') – Numeric form for complex
Ztensors. Ignored for real arrays (e.g., resistivity/phase).return_freqs (bool, default=False) – If
True, also return the reference frequency vector.freqs (array-like, optional) – Precomputed reference frequency grid. If given, it is used directly and
get_full_frequencyis not called. The grid should include (or supersede) each site’s frequencies; any missing values will be filled withNaNduring alignment.**kws – Extra keywords forwarded to the frequency extractor when
freqsis not provided.
- Returns:
mat2d (ndarray (n_freq, n_stations)) – 2-D matrix of the requested tensor component.
(mat2d, freqs) (tuple) – If
return_freqs=True, also returns the frequency vector.
- Raises:
EMError – If inputs are missing, mixed, or illegal (e.g., frequency requested as the primary tensor here).
ValueError – If an unknown
kindis used for complexZ.
Notes
Each item in the input provides a 3-D tensor of shape
(n_freq, 2, 2). Index positions map as:xx -> (0, 0) xy -> (0, 1) yx -> (1, 0) yy -> (1, 1)
Examples
>>> phase_yx = tensor2d(data, tensor='phase', component='yx') >>> phase_yx.shape (56, 7)
- pycsamt.emtools.legacy.align_tensor(ref_freq, site_freq, z, fill_value=nan)#
Align a tensor component to a reference frequency grid.
The reference frequency grid (
ref_freq) is assumed to be the complete set of clean frequencies for the survey. Site-level measurements (site_freq) may be missing some frequencies due to interferences. This function maps the provided tensor values (z) to the reference grid and fills gaps withfill_value.- Parameters:
ref_freq (ArrayLike) – Reference frequency grid collected in the field. It should contain all survey frequencies.
site_freq (ArrayLike) – Frequencies measured at a site. All values must be present in
ref_freq(i.e., no out-of-grid frequencies).z (ndarray of complex) – Tensor component values measured at
site_freq. Typically the real or imaginary part for one ofxx,xy,yx, oryy. Length must matchsite_freq.fill_value (float, default=nan) – Value used to fill positions in the reference grid where the site tensor is missing.
- Returns:
Array aligned to
ref_freqwith gaps filled byfill_value. The dtype matchesz.dtype.- Return type:
ndarray of complex
- Raises:
EMError – If the number of mappable positions inferred from
site_freqdoes not match the length ofz.ValueError – If input shapes are inconsistent.
Notes
Internally uses
ismissing()to identify positions inref_freqthat correspond tosite_freq. The function does not interpolate values; it only aligns and fills gaps.Examples
>>> ref_freq = np.linspace(7e7, 1.0, 20) >>> site_freq = np.hstack([ref_freq[:7], ref_freq[12:]]) >>> z = np.random.randn(len(site_freq)) + 1j*np.random.randn( ... len(site_freq) ... ) >>> z_aligned = align_tensor(ref_freq, site_freq, z) >>> np.isnan(z_aligned).sum() # gaps inserted 5
- pycsamt.emtools.legacy.export_edis(edi_objs, new_z, savepath=None, **kws)#
Export new EDI files from a batch of EDI objects and Z tensors.
Applies updated impedance tensors to each input EDI object and writes new EDI files. This is typically used after applying corrections or replacements to the impedance tensor.
- Parameters:
edi_objs (list of
Edi) – Collection of EDI objects. All elements must be instances ofEdi(noZobjects are allowed here).new_z (list of ndarray (nfreq, 2, 2), complex) – Collection of impedance tensors matching
edi_objsone-to- one. Each tensor is a 3-D complex array with shape(n_freq, 2, 2).savepath (str, optional) – Directory to write the new EDI files. If
None, the EDI writer decides (often the current directory).**kws – Extra arguments forwarded to the EDI writer method
Edi.write_new_edifile(e.g., naming options).
- Returns:
Files are written as a side effect. The underlying writer may return paths, but this function does not collect them.
- Return type:
None
- Raises:
EdIDataError – If
edi_objsdoes not contain exclusively EDI objects.ValueError – If the lengths of
edi_objsandnew_zdiffer.
See also
exportediHelper for exporting a single EDI (if available in the API).
Examples
>>> # edi_objs: list[Edi], z_list: list[np.ndarray] >>> export_edis(edi_objs, z_list, savepath="out/")
- pycsamt.emtools.legacy.plot_confidence(z_or_edis_obj_list, /, tensor='res', view='1d', drop_outliers=True, distance=None, c_line=False, view_ci=True, figsize=(6.0, 2.0), fontsize=4.0, dpi=300, top_label='Stations', rotate_xlabel=90.0, fbtw=True, savefig=None, **plot_kws)#
Plot confidence diagnostics from tensor errors for EM data.
The default tensor for confidence evaluation is the resistivity error at TE mode (
'xy'). This plot helps decide which frequencies (and stations) are reliable, recoverable, or should be discarded before further processing.Three confidence levels are highlighted:
High: \(conf \ge 0.95\)
Soft: \(0.5 \le conf < 0.95\) (often recoverable)
Bad: \(conf < 0.5\) (usually discard)
- Parameters:
z_or_edis_obj_list (list of EDI or Z) – Collection of
EdiorZobjects.tensor (str, default='res') – Tensor selector. Accepted aliases include resistivity (
'res','rho','rhoa'), phase ('phase','phs'), or'z'. Error arrays are used for resistivity/phase automatically.view ({'1d', '2d'}, default='1d') – Plot as a 1-D profile (by station) or as a 2-D map (frequency vs. station).
drop_outliers (bool, default=True) – If
True, suppress outliers in the error tensor before plotting (filled withnan).distance (float, optional) – Inter-station distance. Used to scale the x-axis in 1-D view. If
None, a unit spacing of 1 is used.c_line (bool, default=False) – If
Trueandview='2d', overlay the confidence line.view_ci (bool, default=True) – If
True, show markers indicating confidence classes.figsize (tuple of float, default=(6.0, 2.0)) – Matplotlib figure size.
fontsize (float, default=4.0) – Base font size used for labels and ticks.
dpi (int, default=300) – Figure resolution in dots per inch.
top_label (str, default='Stations') – Title used for the top x-axis (station labels).
rotate_xlabel (float, default=90.0) – Rotation angle for station labels on the top x-axis.
fbtw (bool, default=True) – In 1-D view, fill between the curve and confidence bands.
savefig (str, optional) – Path to save the figure. If
None, the figure is shown.plot_kws (Any)
- Returns:
The Matplotlib Axes with the plotted content.
- Return type:
Notes
Internally, the function computes an error tensor for the chosen
tensor(resistivity/phase use error arrays). Confidence is aggregated across stations and displayed either as a 1-D line or a 2-D image with categorical markers.Examples
>>> ax = plot_confidence( ... emobj.ediObjs_, distance=20, view='2d', ... figsize=(6, 2) ... ) >>> ax = plot_confidence( ... emobj.ediObjs_, distance=20, view='1d', ... figsize=(6, 3), fontsize=5 ... )
- pycsamt.emtools.legacy.plot_strike(list_of_edis, /, kind=2, period_tolerance=0.05, text_pad=1.65, rot_z=0.0, **kws)#
Plot strike angles from invariants and phase tensor as rose/polar diagrams.
Accepts a single .edi file path, a directory containing .edi files, or an iterable of .edi paths. Files are validated before plotting. Output is produced by
mtpy.imaging.plotstrike. PlotStrike, with console output muted.- Parameters:
list_of_edis (str or iterable of str) – Path to an .edi file, a directory of .edi files, or a list/tuple of .edi file paths.
kind ({1, 2}, default=2) –
Plot style for
PlotStrike: -1: plot individual decades in one plot. -2: plot all period ranges in a polar diagram for eachstrike estimate.
period_tolerance (float, default=0.05) – Tolerance to match periods across different EDI files.
text_pad (float, default=1.65) – Padding of the angle label at the bottom of each polar diagram.
rot_z (float, default=0.0) – Clockwise rotation (degrees) applied to the tensor.
**kws – Extra keyword arguments forwarded to
PlotStrike(e.g.,plot_range,plot_tipper,fold,plot_orientation, color settings, etc.).
- Returns:
Plots are created as a side effect.
- Return type:
None
Notes
Files are validated with
IsEdi._assert_edi.Third-party output is muted via
nullify_output().
Examples
>>> plot_strike("/path/to/edis_dir") >>> plot_strike("/path/to/site.edi", kind=1) >>> plot_strike(["a.edi", "b.edi"], rot_z=10.0)
- pycsamt.emtools.legacy.plot_tensors(z_or_edis_obj_list, /, station='S00', zplot=False, show_error_bars=False, **kwargs)#
Plot tensors for one station (compat wrapper).
This is a compatibility wrapper around
plot_station_tensors(). It preserves the legacy API—station,zplot(for impedance vs. app. resistivity/ phase), andshow_error_bars—and forwards any additional styling options to the underlying plotter.- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Collection of EM objects containing either
Edi(from which the embeddedZis extracted) orZdirectly.station (int or str, default='S00') – Target station index or label. Strings such as
'S00'are parsed to 0-based indices.zplot (bool, default=False) – If
True, plot real/imag parts of the impedance tensor (Z). IfFalse, plot apparent resistivity and phase.show_error_bars (bool, default=False) – Whether to display error bars.
**kwargs – Additional plotting options passed to
plot_station_tensors()(e.g.,color_mode, markers, line widths, legend style, font sizes, etc.).
- Returns:
The
Zobject for the selected station.- Return type:
Notes
The heavy lifting (layout, filtering, styling) is handled by
plot_station_tensors(). This wrapper exists to maintain source compatibility with v1.x code.Examples
>>> z = plot_tensors(edi_list, station='S03', zplot=True) >>> z = plot_tensors(edi_list, station=0, show_error_bars=True)
- pycsamt.emtools.legacy.plot_station_tensors(z_or_edis_obj_list, /, station='S00', *, plot_z=False, show_error_bars=True, **kwargs)#
Plot tensors for one station: resistivity/phase or Z real/imag.
By default, the function plots apparent resistivity and phase panels for the four components (xx, xy, yx, yy). If
plot_zisTrue, it plots the real and imaginary parts of the impedance tensor instead. Error bars can be displayed or hidden.- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Collection containing either
EdiorZobjects. When EDI objects are provided, the embeddedZis extracted.station (int or str, default='S00') – Target station index or label. Strings like
'S00'are parsed to an integer index (0-based).plot_z (bool, default=False) – If
True, plot real/imag parts ofZ. Otherwise, plot apparent resistivity and phase.show_error_bars (bool, default=True) – Whether to include error bars on each panel.
**kwargs –
Plot customization such as: -
fig_size(tuple, default=(6, 6)) -dpi(int, default=300) -subplot_wspace(float, default=0.3) -phase_limits(tuple[min,max] in deg) -freq_limits(tuple[min,max] in Hz) -period_limits(tuple[min,max] in s) -mod_base(int, default=360) - style:color_mode(‘color’|’bw’), markers, line widths,legend style, font sizes, etc.
- Returns:
The
Zobject for the selected station.- Return type:
Notes
The function expects the station’s
Zobject to provide (or compute on demand) the following arrays with shape(n_freq, 2, 2): -resistivity,resistivity_err-phase,phase_err-z(complex),z_err(complex) and a frequency vector_freq(Hz).Examples
>>> z = plot_station_tensors(edi_list, station=3) >>> z = plot_station_tensors( ... edi_list, station="S00", plot_z=True, ... show_error_bars=False, color_mode="bw" ... )
- pycsamt.emtools.legacy.wrap_phase(phase, value_range=None, mod_base=360)#
Wrap phase values to a target range with a given periodic base.
By default, phases are wrapped into the interval
[0, mod_base). Whenvalue_rangeis provided, the wrapped phases are linearly remapped from[0, mod_base)to the desired interval.- Parameters:
phase (array-like) – Phase values (any shape), possibly negative or outside the target range.
value_range ({None, scalar, (min, max)}, optional) – Target interval for the output. -
None: return values in[0, mod_base). - scalar: treated as(0, scalar). - tuple/list(min, max): custom interval;min < max.mod_base ({90, 180, 270, 360}, default=360) – Periodicity used for wrapping (degrees).
- Returns:
Wrapped (and optionally remapped) phase values with the same shape as the input and dtype float.
- Return type:
np.ndarray
Notes
For the common symmetric range
(-180, 180], setvalue_range=(-180, 180)withmod_base=360.The remapping is affine: values in
[0, mod_base)are scaled to[min, max).
Examples
>>> x = np.array([-540, -180, 0, 180, 360, 540]) >>> # Default: [0, 360) >>> wrap_phase(x, mod_base=360) array([180., 180., 0., 180., 0., 180.])
>>> # Symmetric range (-180, 180) >>> wrap_phase(x, value_range=(-180, 180), mod_base=360) array([-180., -180., 0., 180., 0., 180.])
>>> # Custom half-range [0, 180) >>> wrap_phase(x, value_range=180, mod_base=360) array([90., 90., 0., 90., 0., 90.])
- pycsamt.emtools.legacy.plot_lcurve(rms, roughness, tau=None, hansen_point=None, rms_target=None, view_tline=False, hpoint_kws=None, fig_size=(10.0, 4.0), ax=None, fig=None, style='classic', savefig=None, **plot_kws)#
Plot the Hansen L-curve (RMS vs. roughness) with annotations.
The L-curve criterion helps select a suitable model after running several inversions with different \(\tau\) values. This function plots RMS against model roughness, optionally highlights the Hansen knee point, displays the RMS target line, and labels each point with its \(\tau\).
- Parameters:
rms (array-like) – Sequence of RMS values, one per inversion.
roughness (array-like) – Sequence of roughness values matching
rms.tau (array-like, optional) – Sequence of \(\tau\) values to annotate at each point. Length must match
rmsandroughness.hansen_point ({'auto', (x, y)}, optional) – If
'auto', the knee point is detected automatically. Otherwise, pass a 2-tuple(roughness, rms)to highlight.rms_target (float, optional) – Target RMS. If provided and
view_tline=True, a horizontal line is drawn at this value. If provided andview_tline=False, the y-limits are expanded around it.view_tline (bool, default=False) – Whether to draw the target RMS horizontal line.
hpoint_kws (dict, optional) – Matplotlib kwargs to style the Hansen point marker.
fig_size (tuple of float, default=(10.0, 4.0)) – Figure size used when creating a new figure.
ax (matplotlib.axes.Axes, optional) – Target axes. If
None, a new figure/axes is created.fig (matplotlib.figure.Figure, optional) – Figure handle used for saving when
savefigis set. If omitted, the figure fromaxis used or a new one created.style (str, optional) – Matplotlib style to use within a context (not global).
savefig (str, optional) – Path to save the figure. If omitted, the plot is shown.
**plot_kws – Extra style passed to
Axes.plotfor the L-curve line.
- Returns:
The axes with the plotted L-curve.
- Return type:
Notes
Knee detection uses a simple triangle-area curvature surrogate. See Hansen & O’Leary (1993) for background on the L-curve.
Examples
>>> rough = [0, 50, 100, 150, 200, 250, 300, 350] >>> rmse = [3.16, 3.12, 3.10, 3.08, 3.06, 3.04, 3.02, 3.00] >>> plot_lcurve(rmse, rough, hansen_point="auto")
- pycsamt.emtools.legacy.get_full_frequency(z_or_edis_obj_list, /, to_log10=False)#
Return the reference (clean) frequency grid for a collection.
The full frequency grid is taken from the site that contains the largest number of frequency samples (i.e., the most complete set). This is commonly used as the survey reference grid to which per-site tensors are aligned.
- Parameters:
- Returns:
The reference frequency vector.
- Return type:
- Raises:
TypeError – If the input is empty or not iterable.
EMError – If the collection mixes Edi and Z, or any element is missing a frequency attribute.
ValueError – If
to_log10=Trueand any frequency is non-positive.
Notes
For each object, the function looks for
.Z._freq/.Z.freq(whenEdi) or._freq/.freq(whenZ), using the first available attribute.Examples
>>> f = full_freq(edi_data) >>> f.shape (56,) >>> flog = full_freq(edi_data, to_log10=True)
- pycsamt.emtools.legacy.qc(z_or_edis_obj_list, /, tol=0.5, *, interpolate_freq=False, return_freq=False, tensor='res', return_data=False, to_log10=False, return_qco=False)#
Assess data quality across a collection of EDI/Z objects.
Computes a global completeness ratio \(1 - \#NaN / (N_{freq} N_{sta})\) from a 2-D tensor (freq × station). Frequencies whose per-row missing-data fraction exceeds
tolare dropped. Optionally interpolate the retained frequencies and/or return a structured summary object.- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Homogeneous collection of EM objects.
tol (float, default=0.5) – Tolerance threshold in
[0, 1]. A frequency row is considered invalid and dropped when its fraction of missing values exceedstol.interpolate_freq (bool, default=False) – If
True, interpolate the retained frequencies on a log-spaced grid spanning[min, max]with the same count.return_freq (bool, default=False) – If
True, return the retained (possibly interpolated) frequency vector.tensor ({'z','res','rho','rhoa','phase','phs'}, default='res') – Tensor family used for QC. The function first attempts the TE component (
'xy'); on failure, it falls back to TM ('yx').return_data (bool, default=False) – If
True, also return the subset of the tensor data corresponding to retained frequencies.to_log10 (bool, default=False) – If
True, returnlog10of the retained frequencies. Applied after interpolation ifinterpolate_freqis set.return_qco (bool, default=False) –
If
True, return aBunchwith the following attributes:rate_: global completeness ratiocomponent_: selected component,'xy'or'yx'mode_: EM mode,'TE'or'TM'freqs_: retained (optionally interpolated) frequenciesinvalid_freqs_: frequencies dropped by the QCdata_: tensor data at retained frequencies
Setting this flag forces
return_freq=Trueandreturn_data=True.
- Returns:
Depending on the flags.
rateis in[0, 1].- Return type:
Notes
The 2-D tensor has shape
(n_freq, n_stations). The per-row missing-data fraction isnan_count / n_stations.Examples
>>> rate, = compute_qc(data) >>> rate, freqs = compute_qc(data, return_freq=True) >>> rep = compute_qc(data, return_qco=True) >>> rep.rate_, rep.component_, rep.freqs_.shape (0.75, 'xy', (56,))
- pycsamt.emtools.legacy.plot_tensors2(z_or_edis_obj_list, /, station='S00', *, plot_z=False, show_error_bars=True, **kwargs)#
Plot tensors for one station: resistivity/phase or Z real/imag.
By default, the function plots apparent resistivity and phase panels for the four components (xx, xy, yx, yy). If
plot_zisTrue, it plots the real and imaginary parts of the impedance tensor instead. Error bars can be displayed or hidden.- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Collection containing either
EdiorZobjects. When EDI objects are provided, the embeddedZis extracted.station (int or str, default='S00') – Target station index or label. Strings like
'S00'are parsed to an integer index (0-based).plot_z (bool, default=False) – If
True, plot real/imag parts ofZ. Otherwise, plot apparent resistivity and phase.show_error_bars (bool, default=True) – Whether to include error bars on each panel.
**kwargs –
Plot customization such as: -
fig_size(tuple, default=(6, 6)) -dpi(int, default=300) -subplot_wspace(float, default=0.3) -phase_limits(tuple[min,max] in deg) -freq_limits(tuple[min,max] in Hz) -period_limits(tuple[min,max] in s) -mod_base(int, default=360) - style:color_mode(‘color’|’bw’), markers, line widths,legend style, font sizes, etc.
- Returns:
The
Zobject for the selected station.- Return type:
Notes
The function expects the station’s
Zobject to provide (or compute on demand) the following arrays with shape(n_freq, 2, 2): -resistivity,resistivity_err-phase,phase_err-z(complex),z_err(complex) and a frequency vector_freq(Hz).Examples
>>> z = plot_station_tensors(edi_list, station=3) >>> z = plot_station_tensors( ... edi_list, station="S00", plot_z=True, ... show_error_bars=False, color_mode="bw" ... )
- pycsamt.emtools.legacy.plot_l_curve(rms, roughness, tau=None, hansen_point=None, rms_target=None, view_tline=False, hpoint_kws=None, fig_size=(10.0, 4.0), ax=None, fig=None, style='classic', savefig=None, **plot_kws)#
Plot the Hansen L-curve (RMS vs. roughness) with annotations.
The L-curve criterion helps select a suitable model after running several inversions with different \(\tau\) values. This function plots RMS against model roughness, optionally highlights the Hansen knee point, displays the RMS target line, and labels each point with its \(\tau\).
- Parameters:
rms (array-like) – Sequence of RMS values, one per inversion.
roughness (array-like) – Sequence of roughness values matching
rms.tau (array-like, optional) – Sequence of \(\tau\) values to annotate at each point. Length must match
rmsandroughness.hansen_point ({'auto', (x, y)}, optional) – If
'auto', the knee point is detected automatically. Otherwise, pass a 2-tuple(roughness, rms)to highlight.rms_target (float, optional) – Target RMS. If provided and
view_tline=True, a horizontal line is drawn at this value. If provided andview_tline=False, the y-limits are expanded around it.view_tline (bool, default=False) – Whether to draw the target RMS horizontal line.
hpoint_kws (dict, optional) – Matplotlib kwargs to style the Hansen point marker.
fig_size (tuple of float, default=(10.0, 4.0)) – Figure size used when creating a new figure.
ax (matplotlib.axes.Axes, optional) – Target axes. If
None, a new figure/axes is created.fig (matplotlib.figure.Figure, optional) – Figure handle used for saving when
savefigis set. If omitted, the figure fromaxis used or a new one created.style (str, optional) – Matplotlib style to use within a context (not global).
savefig (str, optional) – Path to save the figure. If omitted, the plot is shown.
**plot_kws – Extra style passed to
Axes.plotfor the L-curve line.
- Returns:
The axes with the plotted L-curve.
- Return type:
Notes
Knee detection uses a simple triangle-area curvature surrogate. See Hansen & O’Leary (1993) for background on the L-curve.
Examples
>>> rough = [0, 50, 100, 150, 200, 250, 300, 350] >>> rmse = [3.16, 3.12, 3.10, 3.08, 3.06, 3.04, 3.02, 3.00] >>> plot_lcurve(rmse, rough, hansen_point="auto")
- pycsamt.emtools.legacy.get2dtensor(z_or_edis_obj_list, /, tensor='z', component='xy', kind='modulus', return_freqs=False, freqs=None, **kws)#
Build a 2-D matrix (freq × station) from a tensor collection.
Converts a collection of
EdiorZobjects into a 2-D array where rows are frequencies and columns are stations. Missing per-site frequencies are filled withNaN(no interpolation).- Parameters:
z_or_edis_obj_list (list of Edi or Z) – Collection of EM objects. All items must be
Edior allZ.tensor (str, default='z') – Tensor name or alias. Examples include
'z','res'/'rho'/'rhoa','phase'/'phs'. Error arrays are supported (e.g.,'resistivity_err').component ({'xx','xy','yx','yy'}, default='xy') – Component to extract for non-frequency tensors.
kind ({'modulus','real','imag','complex'}, default='modulus') – Numeric form for complex
Ztensors. Ignored for real arrays (e.g., resistivity/phase).return_freqs (bool, default=False) – If
True, also return the reference frequency vector.freqs (array-like, optional) – Precomputed reference frequency grid. If given, it is used directly and
get_full_frequencyis not called. The grid should include (or supersede) each site’s frequencies; any missing values will be filled withNaNduring alignment.**kws – Extra keywords forwarded to the frequency extractor when
freqsis not provided.
- Returns:
mat2d (ndarray (n_freq, n_stations)) – 2-D matrix of the requested tensor component.
(mat2d, freqs) (tuple) – If
return_freqs=True, also returns the frequency vector.
- Raises:
EMError – If inputs are missing, mixed, or illegal (e.g., frequency requested as the primary tensor here).
ValueError – If an unknown
kindis used for complexZ.
Notes
Each item in the input provides a 3-D tensor of shape
(n_freq, 2, 2). Index positions map as:xx -> (0, 0) xy -> (0, 1) yx -> (1, 0) yy -> (1, 1)
Examples
>>> phase_yx = tensor2d(data, tensor='phase', component='yx') >>> phase_yx.shape (56, 7)