seidart.routines.definitions module¶
- seidart.routines.definitions.agc(ts: ndarray, k: int, agctype: str) ndarray¶
Applies auto-gain control (AGC) normalization to a time series using a specified window length and type. This function normalizes the input time series using a running window approach, with the normalization type determined by agctype. It supports standard deviation (“std”), mean (“mean”), or median (“median”) based normalization. The function modifies the series to have a uniform amplitude characteristic over time.
- Parameters:
ts (np.ndarray) – The input time series as a numpy array.
k (int) – The length of the window used for normalization.
agctype (str) – The type of normalization to apply, choices are “std”, “mean”, or “median”.
- Returns:
The time series after applying AGC normalization.
- Return type:
np.ndarray
- seidart.routines.definitions.airsurf(material, domain, N: int = 2) ndarray¶
Generates a gradient matrix to simulate the air surface in a domain, based on material properties.
This function calculates a gradient matrix representing the transition between air and non-air materials within a domain. It is particularly useful for creating a surface with variable density or other properties near the air-material interface.
- Parameters:
- Returns:
A gradient matrix representing the air surface within the domain.
- Return type:
np.ndarray
The function uses the domain’s geometry to determine air interfaces and applies a gradational approach to simulate the air surface effect. The gradient matrix can be used to adjust physical properties like density near the surface.
- seidart.routines.definitions.coherdt(alpha: float, v: float, n: int, dx: float, loc: str = 'left') ndarray¶
Calculates a vector of time delays based on the angle of incidence, velocity, and spatial discretization.
This function determines the time delay for coherent addition of traces based on the propagation angle (alpha), velocity (v), and the discretization in space (dx) along the domain length.
- Parameters:
alpha (float) – The angle of incidence in degrees, counter clockwise from the x-plane. Range: (-90, 90).
v (float) – Velocity in meters/second.
n (int) – The number of spatial points in the domain.
dx (float) – The spatial discretization in meters.
loc (str) – Specifies the reference point’s location for time delay calculation, defaults to ‘left’.
- Returns:
A numpy array containing the time delays for each spatial point in the domain.
- Return type:
np.ndarray
The function adjusts angles outside the (-90, 90) range and calculates time delays accordingly.
- seidart.routines.definitions.coherstf(timediff: ndarray, source_function: ndarray, dt: float, m: int, n: int, cpml: int, bottom: bool = False) None¶
Applies time shifts to a source time function along the domain and saves it as an m-by-n-by-p matrix.
- Parameters:
timediff (np.ndarray) – A numpy array containing time differences for time shifting the source function.
sf (np.ndarray) – The source time function as a numpy array.
dt (float) – The time interval between successive samples in the source function.
m (int) – Number of indices in the y-direction (height of the domain).
n (int) – Number of indices in the x-direction (width of the domain).
cpml (int) – The size of the Convolutional Perfectly Matched Layer (CPML) padding.
bottom (bool) – Specifies whether to place the source at the bottom of the domain. Defaults to False.
- Returns:
None
This function time shifts the source time function for each node in the x-direction, considering CPML adjustments.
‘topleft’ origin is (0,0), ‘topright’ origin is (x_n, 0) ‘bottomleft’ origin is (0, y_n), ‘bottomright’ origin is (x_n, y_n)
- seidart.routines.definitions.complex2str(complex_vector: ndarray) str¶
Convert a numpy array of complex numbers into a string representation, with the first element representing an identifier and the subsequent elements representing complex numbers.
This function extracts the real and imaginary parts of each complex number in the input vector, converts them to strings, and concatenates them with ‘j’ as the delimiter. The first real number of the input vector is treated as an identifier (ID) and is converted separately.
- Parameters:
complex_vector (np.ndarray) – A numpy array of complex numbers where the first element is an ID.
- Returns:
A string representation of the ID followed by the complex numbers in the vector.
- Return type:
str
The returned string format is ‘ID,real1jimag1,real2jimag2,…’ where ID is the integer ID, and realN and imagN are the real and imaginary parts of the Nth complex number, respectively.
- seidart.routines.definitions.compute_dispersion(seismograms: ndarray[tuple[Any, ...], dtype[floating]], dx: float, dt: float, fmin: float, fmax: float, nfreq: int = 50) Tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]¶
Estimate phase-velocity dispersion from a 2D seismogram gather.
A linear phase-vs-distance trend is fitted for each selected frequency bin, with \(2\pi\) branch correction applied to unwrap the overall phase slope. The resulting wavenumber is converted to phase velocity, which is then clamped to a physically plausible range.
- Parameters:
seismograms (numpy.typing.NDArray[numpy.floating]) – Input seismogram gather with shape
(nt, nx), wherentis the number of time samples andnxis the number of spatial traces.dx (float) – Spatial sampling interval in meters.
dt (float) – Time sampling interval in seconds.
fmin (float) – Minimum frequency in Hz for dispersion estimation.
fmax (float) – Maximum frequency in Hz for dispersion estimation.
nfreq (int) – Number of frequency samples between
fminandfmaxto evaluate. Default is50.
- Returns:
A tuple
(freqs, vs)where:freqsis a 1D array of frequencies in Hz, andvsis a 1D array of phase velocities in m/s for each frequency, with invalid or out-of-range estimates set toNaN.- Return type:
tuple
Note
For each target frequency, the complex spectrum is extracted across all traces, the phase is unwrapped, and a linear fit of phase versus distance is computed. A \(2\pi\) branch correction ensures that the fitted slope is consistent over the aperture.
The maximum physically resolvable velocity is taken as
dx / dtbased on the spatial and temporal sampling. Phase-velocity estimates outside(0, max_vel]are rejected and stored asNaNin the output.# Example: compute a dispersion curve from a synthetic gather nt, nx = 2048, 48 dt, dx = 0.004, 5.0 seismograms = np.random.randn(nt, nx) freqs, vs = compute_dispersion( seismograms, dx=dx, dt=dt, fmin=2.0, fmax=40.0, nfreq=60, )
- seidart.routines.definitions.compute_dispersion_image(seismograms: ndarray[tuple[Any, ...], dtype[floating]], dx: float, dt: float, fmin: float, fmax: float, nv: int = 100, nfreq: int = 100, vmin: float | None = None, vmax: float | None = None) Tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]¶
Compute a MASW-style dispersion image and phase-velocity picks.
A multi-channel analysis of surface waves (MASW) slant-stack is formed over a range of trial phase velocities and frequencies. The resulting f–v image is normalized, smoothed, and used to perform sub-bin parabolic peak picking of the dominant dispersion curve.
- Parameters:
seismograms (numpy.typing.NDArray[numpy.floating]) – Input seismogram gather with shape
(nt, nx), wherentis the number of time samples andnxis the number of spatial traces.dx (float) – Spatial sampling interval in meters.
dt (float) – Time sampling interval in seconds.
fmin (float) – Minimum frequency in Hz for the dispersion image.
fmax (float) – Maximum frequency in Hz for the dispersion image.
nv (int) – Number of phase-velocity samples between
vminandvmax. Default is100.nfreq (int) – Number of frequency samples between
fminandfmaxfor the image and picks. Default is100.vmin (float or None) – Minimum phase velocity in m/s for the image. If
None, it is estimated from initial phase picks.vmax (float or None) – Maximum phase velocity in m/s for the image. If
None, it is estimated from initial phase picks.
- Returns:
A tuple
(freqs, vs, image, picks)where:freqsis a 1D array of frequencies in Hz,vsis a 1D array of trial phase velocities in m/s,imageis a 2D normalized dispersion image with shape(len(freqs), len(vs)), andpicksis a 1D array of sub-bin phase-velocity picks (m/s) at each frequency, with out-of-bounds values set toNaN.- Return type:
tuple
- Raises:
ValueError – If the automatically or manually determined velocity bounds satisfy
vmin >= vmax.
Note
Initial phase-velocity estimates are obtained via
compute_dispersion()and used to set automatic bounds whenvminandvmaxare not provided. If these picks are unavailable, fallback bounds are based on the sampling ratiodx / dt.For each frequency, complex amplitudes are slant-stacked over trial velocities using an exponential steering term. The image is normalized per frequency, smoothed with a Gaussian filter, and a parabolic fit around the maximum value in each row is used to obtain sub-bin phase-velocity picks.
# Example: build a dispersion image and picks from a gather nt, nx = 2048, 48 dt, dx = 0.004, 5.0 seismograms = np.random.randn(nt, nx) freqs, vs, image, picks = compute_dispersion_image( seismograms, dx=dx, dt=dt, fmin=2.0, fmax=40.0, nv=120, nfreq=80, )
- seidart.routines.definitions.compute_envelope(signal: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], pad_width: int = 50) ndarray[tuple[Any, ...], dtype[floating]]¶
Compute the amplitude envelope of a 1D signal using the Hilbert transform.
The signal is first padded by reflection at both ends to reduce edge effects in the Hilbert transform. The envelope is then computed on the padded signal and the padding is removed before returning.
- Parameters:
signal (ArrayLike) – Real-valued input signal.
pad_width (int) – Number of samples to pad on each side using reflection. The input length must be at least
2 * pad_width.
- Returns:
Amplitude envelope of the input signal with the same length as the original (unpadded) signal.
- Return type:
numpy.typing.NDArray[numpy.floating]
- Raises:
ValueError – If the input signal is shorter than
2 * pad_width.
Note
Reflection padding helps mitigate boundary artifacts introduced by the Hilbert transform. If the signal is very short or strongly non-stationary near the edges, you may need to adjust
pad_widthto obtain a stable envelope.
- seidart.routines.definitions.compute_fk_spectrum(data: ndarray[tuple[Any, ...], dtype[floating]], dt: float, dx: float, taper: bool = True, ntfft: int | None = None, nxfft: int | None = None, fmin: float = 0.0, fmax: float | None = None, kmin: float | None = None, kmax: float | None = None, wavenumber_units: str = 'cycles') Tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]]¶
Compute the slant-stack f–k power spectrum of a 2D shot gather.
The input gather is assumed to have time along the first axis and space (offset) along the second axis. A 2D FFT is computed, and the power spectrum is returned as a function of frequency and spatial wavenumber with optional band-limiting in both dimensions.
- Parameters:
data (numpy.typing.NDArray[numpy.floating]) – Input shot gather with shape
(nt, nx)wherentis the number of time samples andnxis the number of spatial traces.dt (float) – Time sampling interval in seconds.
dx (float) – Spatial sampling interval in meters.
taper (bool) – If
True, apply a separable Hann taper in time and space to reduce spectral leakage. Default isTrue.ntfft (int or None) – Number of time samples for the FFT. If
None, usent(no zero-padding).nxfft (int or None) – Number of spatial samples for the FFT. If
None, usenx(no zero-padding).fmin (float) – Minimum frequency in Hz to include in the output.
fmax (float or None) – Maximum frequency in Hz to include in the output. If
None, include up to the Nyquist frequency.kmin (float or None) – Minimum absolute wavenumber to include in the output, expressed in the units specified by
wavenumber_units. IfNone, defaults to0.0.kmax (float or None) – Maximum absolute wavenumber to include in the output, expressed in the units specified by
wavenumber_units. IfNone, defaults to the maximum available wavenumber.wavenumber_units (str) – Units of the output wavenumber axis:
"cycles"for cycles per meter (default) or"radians"for radians per meter.
- Returns:
A tuple
(freqs, ks, P)where:freqsis a 1D array of frequencies in Hz,ksis a 1D array of spatial wavenumbers in the requested units, andPis a 2D power spectrum array with shape(len(freqs), len(ks)).- Return type:
tuple
Note
The temporal frequency axis is constructed using
numpy.fft.rfftfreqand restricted to the range[fmin, fmax]. The spatial wavenumber axis is built fromnumpy.fft.fftfreqandfftshift, and optionally converted to radians per meter.Only wavenumbers whose absolute value lies within
[kmin, kmax]are retained, and the corresponding columns are selected from the shifted power spectrum.# Example: compute an f–k spectrum from synthetic data nt, nx = 1024, 64 dt, dx = 0.004, 10.0 # 4 ms, 10 m data = np.random.randn(nt, nx) freqs, ks, P = compute_fk_spectrum( data, dt=dt, dx=dx, fmin=2.0, fmax=60.0, kmin=0.0, kmax=0.2, wavenumber_units="cycles", )
- seidart.routines.definitions.compute_phase_gain(ts_ref: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], ts: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], f0: float, dt: float) tuple[float, float]¶
Compute phase shift and gain between two time series at a specific frequency.
The function computes the real FFT of both input time series, locates the frequency bin closest to
f0, and evaluates the complex transfer function between the spectra. From this transfer function, it returns the phase shift (in degrees) and gain (in decibels).- Parameters:
ts_ref (ArrayLike) – Reference time series (1D array).
ts (ArrayLike) – Comparison time series, with the same shape as
ts_ref.f0 (float) – Center frequency in Hz at which to compute phase and gain.
dt (float) – Sampling interval in seconds.
- Returns:
A tuple
(phase_deg, gain_db)where:phase_degis the phase shift oftsrelative tots_refatf0, in degrees, andgain_dbis the gain in decibels, computed as20 * log10(|H|)withHthe complex spectral ratio.- Return type:
tuple[float, float]
- Raises:
ValueError – If the input time series do not have the same shape or are empty.
Note
The frequency bin used for the calculation is chosen as the one whose center frequency is closest to
f0in the real FFT frequency grid (as returned bynumpy.fft.rfftfreq). For more accurate estimates at arbitrary frequencies, a longer time series or additional spectral interpolation may be required.If the reference spectrum is (near) zero at the selected bin, the transfer function may be ill-conditioned and the resulting gain or phase can be unstable. It is recommended to check that the reference signal has sufficient energy near
f0.
- seidart.routines.definitions.compute_polar_energy(E_x: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], E_y: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], dt: float, angles: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], to_db: bool = False, corrected: bool = False) ndarray[tuple[Any, ...], dtype[floating]]¶
Compute the integrated energy of the horizontal field projection.
The horizontal field is projected onto multiple polarization angles for a 3-component time series (using the x and y components), and the energy is integrated over time for each projection angle.
- Parameters:
E_x (ArrayLike) – 1D array of the x-component time series.
E_y (ArrayLike) – 1D array of the y-component time series.
dt (float) – Time-step interval in seconds.
angles (ArrayLike) – 1D array of polarization angles in radians at which to project the horizontal field.
to_db (bool) – If
True, convert energies to dB scale using10 * log10(E / E.max()). Default isFalse.corrected (bool) – If
True, apply a cosine-squared baseline correction based on the projection geometry and return the corrected energies in dB. Default isFalse.
- Returns:
Array of shape
(len(angles),)containing the energy at each projection angle. Ifto_dbisTrueandcorrectedisFalse, the values are in dB relative to the maximum energy. IfcorrectedisTrue, the returned values are baseline-corrected and expressed in dB.- Return type:
numpy.typing.NDArray[numpy.floating]
Note
For each angle \(\theta\), the horizontal field is projected as \(E_\theta = E_x \cos(\theta) + E_y \sin(\theta)\), and the energy is computed as the discrete integral \(\sum |E_\theta|^2 \Delta t\).
When
correctedisTrue, the raw energy pattern is divided by a cosine-squared baseline (cos(angles)**2) to account for purely geometric projection effects before converting to dB. This can be useful when comparing polarization strength across angles.
- seidart.routines.definitions.correct_geometric_spreading(time_series: ndarray, distances: ndarray, exponent: float = 1.0) ndarray¶
Corrects a seismic time series for geometric spreading.
- Parameters:
time_series (np.ndarray) – The seismic time series data. Should be a numpy array of shape (n_samples, n_traces).
distances (np.ndarray) – The distances from the source to each trace. Should be a numpy array of shape (n_traces,).
exponent (float, optional) – The exponent used in the geometric spreading correction. Defaults to 1.0.
- Raises:
ValueError – If the length of distances does not match the number of traces.
- Returns:
The corrected seismic time series. Will be a numpy array of shape (n_samples, n_traces).
- Return type:
np.ndarray
Example usage:
# Example seismic time series (n_samples x n_traces) time_series = np.random.rand(1000, 10) # Replace with your actual data # Example distances (n_traces,) distances = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # Replace with your actual distances # Apply geometric spreading correction corrected_time_series = correct_geometric_spreading(time_series, distances) print(corrected_time_series)
- seidart.routines.definitions.cpmlcompute(modelclass, domain, half: bool = False, velocity_scaling_factor=1.0, pml_smoothing: bool = 'global', smoothing_window: int = 7, smoothing_passes: int = 1) None¶
Computes CPML parameters for a given direction and updates model/domain.
For 2 / 2.5-D domains the output arrays are 2-D
(nx+2c, nz+2c)and are written as Fortran binary records (row-major transpose).For true 3-D domains (
domain.dim == 3) separate damping profiles are built along x, y, and z independently and the output arrays are 3-D(nx+2c, ny+2c, nz+2c), written in Fortran-array order.- Parameters:
modelclass (Model) – The model class instance to update.
domain (Domain) – The domain class instance to update.
half (bool) – Flag to compute half-step CPML parameters. Defaults to False.
pml_smoothing – Smoothing strategy for the PML boundary values. Options are
None,'global'(default), or'smoothed'.
- seidart.routines.definitions.exponential_gain(time_series: ndarray, dt: float, alpha: float) ndarray¶
Applies an exponential gain to a time series to correct for attenuation.
- Parameters:
time_series (np.ndarray) – The original time series data. Should be a numpy array of shape (n_samples,).
alpha (float) – The attenuation coefficient.
- Returns:
The corrected time series.
- Return type:
np.ndarray
- seidart.routines.definitions.indvar(model_object, domain) tuple[ndarray, ndarray | None, ndarray, ndarray]¶
Generates spatial and temporal grids based on domain and model object attributes.
- Parameters:
model_object – An object containing model-specific parameters, including time steps and time interval (dt).
domain – An object containing domain-specific parameters such as spatial dimensions (nx, ny, nz) and discretizations (dx, dy, dz).
- Returns:
A tuple of numpy arrays representing the grids in x, y (None if ny is not set), z, and t dimensions.
- Return type:
tuple
The function calculates the spatial grid points in the x, z, and optionally y dimensions, and temporal grid points based on the provided domain and model parameters. The y-dimension grid is generated only if the domain parameters include ‘ny’.
- seidart.routines.definitions.loadproject(project_file: str, domain, material, seismic, electromag)¶
Loads project settings from a project file and assigns values to domain, material, seismic, and electromagnetic objects.
This function parses a specified project file, reading configurations and parameters for the domain, materials, seismic modeling, and electromagnetic properties. These parameters are then assigned to the provided objects.
- Parameters:
project_file (str) – The path to the project configuration file.
domain – An object to hold domain-specific parameters and configurations.
material – An object to hold material-specific parameters and configurations.
seismic – An object to hold seismic modeling parameters and configurations.
electromag – An object to hold electromagnetic modeling parameters and configurations.
- Returns:
A tuple containing the updated domain, material, seismic, and electromagnetic objects.
- Return type:
tuple
The function assumes the project file contains specific prefixes for different types of configurations (e.g., ‘I’ for images, ‘D’ for domain configurations, ‘S’ for seismic modeling parameters, etc.).
- seidart.routines.definitions.movingsrc(sf: ndarray, txlocs: ndarray) None¶
Simulates a moving source given a stationary source time function.
- Parameters:
sf (np.ndarray) – The stationary source time function as a numpy array.
txlocs (np.ndarray) – A numpy array containing the transmission locations over time.
- Returns:
None
This function is intended as a placeholder to simulate a moving source by manipulating the stationary source time function according to the provided transmission locations.
- seidart.routines.definitions.plot_3c(time, data1, data2=None, data3=None, data_label1='Data1', data_label2='Data2', data_label3='Data3', source_wavelet=None, arrivals1=None, arrivals2=None, arrivals3=None, component_labels=None, arrival_labels1=None, arrival_labels2=None, arrival_labels3=None, arrival_colors1=None, arrival_colors2=None, arrival_colors3=None, color_data1='black', color_data2='blue', color_data3='green', envelope_color1='lightgray', envelope_color2='lightgray', envelope_color3='lightgray', plot_envelope=True, figsize=(10, 8), show_legend=True, xlims=None, yaxis_rotation=90, envelope_pad_width=50)¶
Plot 3-component seismograms with vertical dashed lines for expected arrival times.
- For each component channel, the function will:
Optionally cross-correlate the channel with a provided source wavelet.
Compute a power envelope (via Hilbert transform with padding to reduce edge effects).
Plot the envelope as a shaded region and overlay the cross-correlated seismogram.
- The function supports up to three datasets:
data1 is required.
data2 and data3 are optional.
Separate arrival times, labels, and line colors can be specified for each dataset.
- Parameters:
time (numpy.ndarray) – 1D array of time values.
data1 (numpy.ndarray) – 2D array (n_samples x 3) for the first set of seismogram components.
data2 (numpy.ndarray, optional) – 2D array (n_samples x 3) for the second set of seismogram components.
data3 (numpy.ndarray, optional) – 2D array (n_samples x 3) for the third set of seismogram components.
source_wavelet (numpy.ndarray, optional) – 1D array containing the source wavelet. If provided, cross correlation is performed.
arrivals1 (dict or list/tuple, optional) – Arrival times for data1. If a list/tuple, must have 3 elements in order [P, S1, S2].
arrivals2 (dict or list/tuple, optional) – Arrival times for data2. If a list/tuple, must have 3 elements in order [P, S1, S2].
arrivals3 (dict or list/tuple, optional) – Arrival times for data3. If a list/tuple, must have 3 elements in order [P, S1, S2].
component_labels (list of str, optional) – Labels for the 3 components. Default is [‘Vertical’, ‘Radial’, ‘Transverse’].
arrival_labels1 (dict, optional) – Arrival labels for data1. Default is {‘P’: ‘P1’, ‘S1’: ‘S1_1’, ‘S2’: ‘S2_1’}.
arrival_labels2 (dict, optional) – Arrival labels for data2. Default is {‘P’: ‘P2’, ‘S1’: ‘S1_2’, ‘S2’: ‘S2_2’}.
arrival_labels3 (dict, optional) – Arrival labels for data3. Default is {‘P’: ‘P3’, ‘S1’: ‘S1_3’, ‘S2’: ‘S2_3’}.
arrival_colors1 (dict, optional) – Colors for vertical dashed lines for data1 arrivals. Default is {‘P’: ‘red’, ‘S1’: ‘red’, ‘S2’: ‘red’}.
arrival_colors2 (dict, optional) – Colors for vertical dashed lines for data2 arrivals. Default is {‘P’: ‘blue’, ‘S1’: ‘blue’, ‘S2’: ‘blue’}.
arrival_colors3 (dict, optional) – Colors for vertical dashed lines for data3 arrivals. Default is {‘P’: ‘green’, ‘S1’: ‘green’, ‘S2’: ‘green’}.
color_data1 (str, optional) – Color for the data1 trace (default ‘black’).
color_data2 (str, optional) – Color for the data2 trace (default ‘blue’).
color_data3 (str, optional) – Color for the data3 trace (default ‘green’).
envelope_color1 (str, optional) – Fill color for the envelope of data1 (default ‘lightgray’).
envelope_color2 (str, optional) – Fill color for the envelope of data2 (default ‘lightgray’).
envelope_color3 (str, optional) – Fill color for the envelope of data3 (default ‘lightgray’).
figsize (tuple, optional) – Figure size.
envelope_pad_width (int, optional) – Padding width (in samples) for the Hilbert transform envelope computation.
- Returns:
fig – The figure handle.
- Return type:
matplotlib.figure.Figure
- seidart.routines.definitions.plot_dispersion(freqs: ndarray[tuple[Any, ...], dtype[floating]], velocities: ndarray[tuple[Any, ...], dtype[floating]]) None¶
Plot a dispersion curve of frequency versus phase velocity.
A simple line plot is created showing phase velocity as a function of frequency, suitable for visualizing dispersion picks or curves.
- Parameters:
freqs (numpy.typing.NDArray[numpy.floating]) – 1D array of frequencies in Hz.
velocities (numpy.typing.NDArray[numpy.floating]) – 1D array of phase velocities in m/s, with the same shape as
freqs.
- Returns:
This function does not return anything; it creates a Matplotlib figure and displays it.
- Return type:
None
Note
This function calls
matplotlib.pyplot.show(), which will block execution in some environments. If you need more control over the figure (e.g., saving to file or embedding in a GUI), consider modifying the code to return the figure and axes instead of callingplt.show()directly.# Example: plot dispersion picks freqs = np.linspace(2.0, 40.0, 50) velocities = 300.0 + 5.0 * freqs # synthetic trend plot_dispersion(freqs, velocities)
- seidart.routines.definitions.plot_dispersion_image(freqs: ndarray[tuple[Any, ...], dtype[floating]], vs: ndarray[tuple[Any, ...], dtype[floating]], image: ndarray[tuple[Any, ...], dtype[floating]], picks_freqs: ndarray[tuple[Any, ...], dtype[floating]] | None = None, picks_vs: ndarray[tuple[Any, ...], dtype[floating]] | None = None, colormap: str = 'inferno') Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]¶
Plot a MASW-style dispersion image with an optional picked curve.
The function displays a frequency–velocity (f–v) image of normalized energy and, if provided, overlays a picked dispersion curve on top of the image.
- Parameters:
freqs (numpy.typing.NDArray[numpy.floating]) – 1D array of frequencies in Hz with shape
(Nf,).vs (numpy.typing.NDArray[numpy.floating]) – 1D array of phase velocities in m/s with shape
(Nv,).image (numpy.typing.NDArray[numpy.floating]) – 2D normalized energy map with shape
(Nf, Nv), typically the output ofcompute_dispersion_image().picks_freqs (numpy.typing.NDArray[numpy.floating] or None) – Optional 1D array of frequencies in Hz for a picked dispersion curve.
picks_vs (numpy.typing.NDArray[numpy.floating] or None) – Optional 1D array of phase velocities in m/s for a picked dispersion curve, matching
picks_freqs.colormap (str) – Matplotlib colormap name used for the image (default
"inferno").
- Returns:
The figure and axes containing the dispersion image plot.
- Return type:
tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]
Note
The energy map is plotted using
matplotlib.axes.Axes.pcolormesh()with transposed data so that frequency appears on the horizontal axis and phase velocity on the vertical axis.When both
picks_freqsandpicks_vsare provided, the picked curve is overlaid as red scatter points and a legend is added in the upper-right corner.# Example: visualize a dispersion image and picked curve freqs, vs, image, picks = compute_dispersion_image( seismograms, dx=5.0, dt=0.004, fmin=2.0, fmax=40.0, ) fig, ax = plot_dispersion_image( freqs, vs, image, picks_freqs=freqs, picks_vs=picks, colormap="inferno", ) plt.show()
- seidart.routines.definitions.plot_fk_spectrum(freqs: ndarray[tuple[Any, ...], dtype[floating]], ks: ndarray[tuple[Any, ...], dtype[floating]], P: ndarray[tuple[Any, ...], dtype[floating]], fig: matplotlib.figure.Figure | None = None, ax: matplotlib.axes.Axes | None = None, vmin: float | None = None, vmax: float | None = None, log_scale: bool = False, smooth: bool = False, smooth_sigma: Tuple[float, float] = (1.0, 1.0), mode_lines: Dict[str, float | Tuple[float, str]] | None = None, wavenumber_units: str = 'cycles') Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]¶
Display an f–k power spectrum.
The f–k power spectrum is shown as a 2D color mesh of power versus frequency and wavenumber, with options for logarithmic scaling, Gaussian smoothing, and overlaying theoretical mode-velocity lines in either cycles/m or rad/m.
- Parameters:
freqs (numpy.typing.NDArray[numpy.floating]) – 1D array of frequencies in Hz, typically the output from
compute_fk_spectrum().ks (numpy.typing.NDArray[numpy.floating]) – 1D array of spatial wavenumbers in either cycles/m or rad/m, matching the
wavenumber_unitssetting.P (numpy.typing.NDArray[numpy.floating]) – 2D power spectrum array with shape
(len(freqs), len(ks)).fig (matplotlib.figure.Figure or None) – Existing Matplotlib
matplotlib.figure.Figureto draw into. IfNone, a new figure is created.ax (matplotlib.axes.Axes or None) – Existing Matplotlib
matplotlib.axes.Axesto draw into. IfNone, a new axes is created.vmin (float or None) – Minimum value for the color scale. If
None, it is determined automatically by Matplotlib.vmax (float or None) – Maximum value for the color scale. If
None, it is determined automatically by Matplotlib.log_scale (bool) – If
True, display power in decibels using10 * log10(P). Default isFalse.smooth (bool) – If
True, apply a Gaussian filter toPbefore plotting. Default isFalse.smooth_sigma (tuple[float, float]) – Standard deviations of the Gaussian smoothing kernel in the (frequency, wavenumber) directions.
mode_lines (dict[str, float or tuple[float, str]] or None) – Optional dictionary defining theoretical mode lines to overlay. Keys are labels; values are either velocities (float) or
(velocity, color)tuples. Velocities are in m/s.wavenumber_units (str) – Units of
ksand the horizontal axis:"cycles"for cycles/m (default) or"radians"for rad/m.
- Returns:
The figure and axes used for the plot.
- Return type:
tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]
Note
When
log_scaleisTrue, a small epsilon is added to the power spectrum before converting to dB to avoid taking the logarithm of zero. Smoothing can help visualize coherent energy trends but may blur fine spectral features.Mode-velocity lines are drawn as pairs of symmetric curves \(\pm k(f)\) for each velocity, computed using \(k = 2 \pi f / v\) for wavenumbers in radians/m or \(k = f / v\) for cycles/m, depending on
wavenumber_units.# Example: plot an f–k spectrum with a fundamental mode line freqs, ks, P = compute_fk_spectrum(data, dt=0.004, dx=10.0) fig, ax = plot_fk_spectrum( freqs, ks, P, log_scale=True, smooth=True, smooth_sigma=(1.0, 2.0), mode_lines={"fundamental": 300.0}, # velocity in m/s ) plt.show()
- seidart.routines.definitions.plot_hodogram(data, dt, window=None, components=('L', 'Q', 'T'), title='Hodogram')¶
Plots hodograms (particle motion plots) from given seismic data and returns the figure and axes objects.
- Parameters:
data (ndarray (N x 3)) – Seismic data array with columns corresponding to [L, Q, T] components.
dt (float) – Time interval between samples (seconds).
window (tuple (start, end), optional) – Time window (in seconds) to select data. If None, uses full data.
components (tuple of str) – Labels for components, default (‘L’, ‘Q’, ‘T’).
title (str) – Plot title.
- Returns:
fig (matplotlib.figure.Figure) – The figure object.
axs (ndarray of matplotlib.axes.Axes) – Array containing the axes objects.
- seidart.routines.definitions.polarization_analysis(data: ndarray[tuple[Any, ...], dtype[floating]], dt: float, M: int, alpha: float = 0.1) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[bool]]]¶
Compute rectilinearity, backazimuth, and incidence angle using a sliding Tukey window.
The analysis uses a sliding window over 3-component motion data to estimate polarization attributes via covariance eigen-decomposition. Near the signal edges, shorter windows are used, and a cone-of-influence mask is returned to indicate where the full window length is available.
- Parameters:
data (numpy.typing.NDArray[numpy.floating]) – 3-component motion data with shape
(N, 3)(e.g., LQT, ZRT, or XYZ).dt (float) – Time step in seconds.
M (int) – Window length in samples.
alpha (float) – Tukey window shape parameter in
[0, 1]. Default is0.1.
- Returns:
A tuple
(times, rectilinearity, backazimuth, incidence, cone_mask)where:timesis the time vector in seconds,rectilinearitycontains rectilinearity values,backazimuthcontains backazimuth angles in degrees from the y-axis,incidencecontains incidence angles in degrees from the vertical,cone_maskis a boolean array that isTruewhere a full-length window is used.- Return type:
tuple
Note
The polarization attributes are computed from the eigenvectors and eigenvalues of the windowed covariance matrix. The principal eigenvector is forced to point in a consistent (upward) direction by flipping it when its vertical component is negative.
Near the series boundaries, the effective window is shorter than
Msamples. In these regions, the estimates may be less stable; thecone_maskoutput can be used to restrict interpretation to times where the full window length is available.
- seidart.routines.definitions.rcxgen(rgb: list, domain, material, filename: str = 'receivers.xyz')¶
Creates a receiver list from a specified RGB value found in the model image, outputting to a CSV file.
This function searches the domain’s geometry for occurrences of a given RGB value (specified as a list of integers representing red, green, and blue components). It then generates a list of receiver coordinates based on the locations where the RGB value is found. Currently, the function is set up for 2D receivers only, with Y-coordinates set to zero.
- Parameters:
rgb (list) – A list of three integers representing the RGB value to search for in the domain’s geometry.
domain – An object representing the domain, including its geometry and spatial discretization parameters (dz, dx).
material – An object containing the material list and associated RGB values.
filename (str) – The name of the output CSV file containing the receiver coordinates, defaults to ‘receivers.xyz’.
- Returns:
A numpy array of receiver coordinates where each row represents [Z, Y, X] coordinates.
- Return type:
np.ndarray
- The function converts the RGB list into a string format, looks up the
corresponding integer value from the
- material list, finds all occurrences in the domain’s geometry, and outputs
the coordinates to a specified CSV file.
- seidart.routines.definitions.read_dat(fn: str, channel: str, domain, single: bool = False) ndarray¶
Read data from an unformatted Fortran binary file and return it as a numpy array. This function supports reading data in single or double precision, and can handle complex data.
The domain parameter is expected to be an object with
dim,nx,ny, andnzattributes. These values determine the shape of the returned array.- Parameters:
fn (str) – The filename of the data file to read.
channel (str) – Specifies the data channel (‘Ex’, ‘Ey’, ‘Ez’, etc.) to read.
domain (Domain) – The domain object that contains dimensions (dim, nx, ny, nz) of the data.
single (bool) – A flag indicating if the data should be read in single precision. Defaults to False (double precision).
- Returns:
The data read from the file, reshaped according to the domain dimensions.
- Return type:
np.ndarray
- seidart.routines.definitions.rotate_sdr(strike: float, dip: float, rake: float, is_degree: bool = True) ndarray[tuple[Any, ...], dtype[floating]]¶
Create a 3D rotation matrix from strike, dip, and rake angles.
The rotation matrix is constructed from three sequential rotations about the global axes corresponding to strike, dip, and rake angles. This is commonly used to transform between fault-plane and global coordinate systems in seismological applications.
- Parameters:
strike (float) – Strike angle. Interpreted as degrees if
is_degreeisTrue, otherwise radians.dip (float) – Dip angle. Interpreted as degrees if
is_degreeisTrue, otherwise radians.rake (float) – Rake (slip) angle. Interpreted as degrees if
is_degreeisTrue, otherwise radians.is_degree (bool) – If
True, input angles are treated as degrees and converted to radians internally. IfFalse, angles are assumed to be in radians.
- Returns:
Rotation matrix of shape
(3, 3)formed asRz(strike) @ Ry(dip) @ Rx(rake).- Return type:
numpy.typing.NDArray[numpy.floating]
Note
The rotation is applied as a product of three basic rotations: about the z-axis by
strike, about the y-axis bydip, and about the x-axis byrake. The precise physical interpretation depends on your coordinate and fault-plane conventions.When using this matrix to rotate vectors
vin the original coordinate system, the transformed vectors can be obtained asv_rot = R @ v.# Example: build a rotation matrix for a given focal mechanism strike, dip, rake = 210.0, 30.0, 90.0 # degrees R = rotate_sdr(strike, dip, rake) v = np.array([1.0, 0.0, 0.0]) v_rot = R @ v # rotated vector
- seidart.routines.definitions.rotate_to_qlt(data: ndarray[tuple[Any, ...], dtype[floating]], source_location: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], receiver_location: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], backazimuth: float | None = None, incidence: float | None = None) tuple[float, float, ndarray[tuple[Any, ...], dtype[floating]]]¶
Rotate 3-component data from Cartesian (x, y, z) to (L, Q, T) components.
The input 3-component data are rotated into the longitudinal (L), quasi-vertical (Q), and transverse (T) directions using geometry defined by the source and receiver locations and, optionally, given backazimuth and incidence angles.
- Parameters:
data (numpy.typing.NDArray[numpy.floating]) – Input data with shape
(N, 3)and columns[vx, vy, vz].source_location (array_like) – Source coordinates
[x, y, z].receiver_location (array_like) – Receiver coordinates
[x, y, z].backazimuth (float or None) – Backazimuth angle in radians (clockwise from the positive y-axis). If
None, it is computed from the source–receiver geometry.incidence (float or None) – Incidence (inclination) angle in radians, positive downward from horizontal. If
None, it is computed from the source–receiver geometry.
- Returns:
A tuple
(ba, inc, lqt)where:bais the backazimuth angle in radians,incis the inclination angle in radians,lqtis the rotated data with shape(N, 3)and columns[L, Q, T].- Return type:
tuple[float, float, numpy.typing.NDArray[numpy.floating]]
Note
When
backazimuthorincidenceis not provided, both are derived from the displacement vectorreceiver_location - source_location. The inclination is taken as the arctangent of the vertical offset over the horizontal distance, and the backazimuth is measured clockwise from the positive y-axis.The rotation matrix is constructed so that the L direction is aligned with the propagation direction, Q lies in the vertical plane containing the propagation direction, and T is the horizontal transverse (SH) direction.
# Example: rotate from vx, vy, vz to L, Q, T using geometry data = np.random.randn(1000, 3) # [vx, vy, vz] src = np.array([0.0, 0.0, 0.0]) rcv = np.array([10.0, 5.0, -2.0]) ba, inc, lqt = rotate_to_qlt(data, src, rcv)
- seidart.routines.definitions.rotate_to_zrt(data: ndarray[tuple[Any, ...], dtype[floating]], source: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None = None, receiver: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None = None, direction: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None = None) ndarray[tuple[Any, ...], dtype[floating]]¶
Rotate seismogram data from Cartesian components to Z, R, T components.
The input 3-component seismogram data (
vx, vy, vz) are rotated into a local coordinate system defined by the vertical, radial, and transverse directions. The radial direction is determined either from a propagation direction vector or from the source–receiver geometry.- Parameters:
data (numpy.typing.NDArray[numpy.floating]) – Seismogram data in Cartesian components, with shape
(n_samples, 3)and components ordered as(vx, vy, vz).source (array_like or None) – Source coordinates as a 3-element array
[x, y, z]. Used together withreceiverwhendirectionis not provided.receiver (array_like or None) – Receiver coordinates as a 3-element array
[x, y, z]. Used together withsourcewhendirectionis not provided.direction (array_like or None) – Propagation direction vector (3 elements). If provided, its horizontal projection defines the radial direction.
- Returns:
Rotated seismogram data with shape
(n_samples, 3)and components ordered as(Z, R, T).- Return type:
numpy.typing.NDArray[numpy.floating]
- Raises:
ValueError – If neither
directionnor a validsourceandreceiverpair is provided, if the direction vector has zero length, or if the source–receiver horizontal separation is effectively zero.
Note
If
directionis provided, it is normalized and its horizontal \((x, y)\) components are used to define the radial direction.If
directionis not provided, bothsourceandreceivermust be given. The horizontal differencereceiver - sourceis used to determine the azimuth and radial direction.The vertical unit vector is assumed to be \([0, 0, 1]\), and the transverse direction is computed as the cross product of the vertical and radial directions, ensuring an approximately right-handed coordinate system.
# Example: rotate from vx, vy, vz to Z, R, T using source/receiver data = np.random.randn(1000, 3) # (vx, vy, vz) source = [0.0, 0.0, 0.0] receiver = [10.0, 5.0, 0.0] zrt = rotate_to_zrt(data, source=source, receiver=receiver)
- seidart.routines.definitions.sponge_boundary(domain, eta_max: float, eta: ndarray[tuple[Any, ...], dtype[floating]]) ndarray[tuple[Any, ...], dtype[floating]]¶
Apply a polynomial sponge boundary to a 2D damping field.
A polynomial sponge profile is added near the domain boundaries to gradually damp outgoing waves. The strength and thickness of the sponge are controlled by attributes of
domain.- Parameters:
domain (Any) – Simulation domain object providing sponge parameters. Must define
cpml(sponge thickness in grid points) andNPS(polynomial order for the sponge profile).eta_max (float) – Maximum sponge damping coefficient applied at the boundaries.
eta (numpy.typing.NDArray[numpy.floating]) – Existing 2D damping field to be modified in place by adding the sponge boundary contribution.
- Returns:
The updated damping field with sponge boundary applied.
- Return type:
numpy.typing.NDArray[numpy.floating]
- seidart.routines.definitions.stfvec2mat(source_function: ndarray, xind: int, zind: int, m: int, n: int, cpml: int, yind: int = None) None¶
Converts a source time function vector to a matrix for 2D or 3D simulations.
- Parameters:
sf (np.ndarray) – The source time function vector.
xind (int) – The index in the x-direction where the source is located.
zind (int) – The index in the z-direction where the source is located.
m (int) – The number of indices in the y-direction (height of the domain).
n (int) – The number of indices in the x-direction (width of the domain).
cpml (int) – The size of the Convolutional Perfectly Matched Layer (CPML) padding.
yind (Optional[int]) – The index in the y-direction where the source is located, for 3D simulations. Defaults to None for 2D simulations.
- Returns:
None
This function arranges the source time function in the spatial domain and applies CPML padding.
- seidart.routines.definitions.str2complex(strsplit: list) ndarray¶
Convert a list of strings into a numpy array of complex numbers, where the first string is treated as an identifier (ID) and the subsequent strings represent complex numbers.
The function splits each string by ‘j’ to separate the real and imaginary parts of each complex number, then constructs a numpy array of complex numbers from these parts. The first element of the array is the ID.
- Parameters:
strsplit (list) – A list of strings, where the first string is an ID and the remaining strings represent complex numbers in ‘realjimag’ format.
- Returns:
A numpy array of complex numbers with the ID as the first element.
- Return type:
np.ndarray
Note that the input list should follow the format [‘ID’, ‘real1jimag1’, ‘real2jimag2’, …], where ‘ID’ is an integer identifier, and ‘realNjimagN’ are the real and imaginary parts of the Nth complex number.