Python API reference

The public Python API uses NumPy arrays throughout. Build and install the libswd extension before running numerical examples. HDF5 support also requires h5py.

Solver workspace

class specd.SpecWorkSpace(wavetype: str = None, has_att: bool = False)[source]

Bases: object

compute_dispersion(frequencies_hz: ndarray, azimuths_deg=0.0, include_group: bool = True)[source]

Compute a frequency/azimuth grid as a CSR dispersion table.

Mode counts may vary between solve points. Rows use frequency-major, azimuth-minor order and remain ordinary NumPy arrays.

compute_egn(freq: float, ang_in_deg=0.0, only_phase=False) → ndarray[source]

compute eigenvalues/eigenvectors

Parameters:
  • freq (float) – current frequency

  • ang_in_deg (float) – phase velocity azimuthal angle, in deg

  • only_phase (bool) – if False, only compute eigenvalues (phase velocities) if True, phase velocities and eigenfunctions will be computed

Returns:

c – phase velocities

Return type:

np.ndarray

get_egnfunc(imode: int, return_displ: bool, return_left=False)[source]

get eigenfunctions at current frequency/mode

Parameters:
  • imode (int) – mode number

  • return_left (bool) – if true, return left eigenvectors else return right eigenvectors

  • return_displ (bool) – if true, return displacement polarization amplitudes instead of eigenvectors. For VTI Rayleigh/Scholte waves, the horizontal and vertical amplitudes retain a real convention; the physical pi/2 phase offset of the vertical component is implicit. For example, the corresponding eigenvector is [u,v^{ar},chi^{ar}].

get_group_kl(imode: int)[source]

compute group velocity sensitivity kernels for mode {imode}

Parameters:

imode (int) – compute kernels at imode, imode elong [0,max_mode)

Returns:

  • frekl_c (np.ndarray) – group velocity kernels, shape(nkers,self._nz)

  • frekl_q (np.ndarray) – group velocity Q kernels,shape(nkers,self._nz), only returns when self._has_att = True

get_kernel_names()[source]

get names for Frechet derivative

Returns:

kl_name – list of kernel names

Return type:

list[str]

get_phase_kl(imode: int)[source]

compute phase velocity sensitivity kernels for mode {imode}

Parameters:

imode (int) – compute kernels at imode, imode elong [0,max_mode)

Returns:

  • frekl_c (np.ndarray) – phase velocity kernels, shape(nkers,self._nz)

  • frekl_q (np.ndarray) – phase velocity Q kernels,shape(nkers,self._nz), only returns when self._has_att = True

get_znodes()[source]

get mesh coordiantes, shape(nspec*NGLL+NGRL)

group_velocity()[source]

compute group velocites for each model at current frequency

Returns:

u – group velocities at current frequency. For general anisotropy, shape is (2, nmodes) with x and y components by row.

Return type:

float/complex

Note

before calling this routine, use_qz should be True in self.compute_egn

initialize(wavetype: str, z: ndarray, rho: ndarray, vph=None, vpv=None, vsh=None, vsv=None, eta=None, Qa=None, Qc=None, Qn=None, Ql=None, c21=None, Qani=None, qfunc_id=1, scale_rho=0.0, scale_v=0.0, scale_z=0.0, disp=False, reference_frequency=1.0)[source]

initialize working space for SEM

Parameters:
  • wavetype (str) – wavetype, one of [‘love’,’rayl’,’aniso’]

  • z (np.ndarray) – depth vector, should include discontinuities at half sapce

  • rho (np.ndarray) – density, shape_like(z)

  • vph/vpv/vsh/vsv (np.ndarray) – VTI parameters, shape_like(z)

  • Qa/Qc/Qn/Ql (np.ndarray) – VTI constant quality factors, shape_like(z)

  • c21 (np.ndarray) – 21 elastic tensor, shape(21,nz)

  • nQani (int) – no. of Q models for fully anisotropy

  • Qnai (np.ndarray) – quality factors, shape(nQnai,nz)

  • disp (bool) – if True print model information

  • reference_frequency (float) – frequency in Hz at which the input storage moduli (and therefore the real input velocities) are defined; default is 1 Hz

Note

The input parameters should be carefully chose by user. For Love wave, only vsh/vsv/Qsh/Qsv can be enabled, and for Rayleigh wave, only vph/vpv/vsv can ve enabled, and other params are for full anisotropy

CSR dispersion containers

class specd.ComplexCSR(indptr: ndarray, mode_index: ndarray, values: ndarray, component_names: Tuple[str, ...])[source]

Bases: object

Complex CSR rows indexed by solve point and local mode number.

component_names: Tuple[str, ...]
classmethod from_rows(rows: Sequence[ndarray], component_names: Sequence[str], mode_rows: Sequence[ndarray] | None = None) → ComplexCSR[source]

Pack variable-length NumPy rows into a CSR container.

indptr: ndarray
mode_index: ndarray
property nentry: int
property nrow: int
row(row: int) → Tuple[ndarray, ndarray][source]

Return (mode_index, values) as zero-copy NumPy views.

validate(nrow: int, name: str = 'csr') → None[source]
values: ndarray
class specd.DispersionTable(frequency_hz: ndarray, azimuth_deg: ndarray, phase_velocity: ComplexCSR, group_velocity: ComplexCSR | None = None, velocity_units: str = 'km/s')[source]

Bases: object

CSR dispersion data on a frequency/azimuth grid.

azimuth_deg: ndarray
frequency_hz: ndarray
classmethod from_hdf5(path) → DispersionTable[source]

Read and validate a version-1 SpecSWD CSR HDF5 file.

classmethod from_rows(frequency_hz, phase_rows: Sequence[ndarray], *, azimuth_deg=(0.0,), phase_mode_rows: Sequence[ndarray] | None = None, group_rows: Sequence[ndarray] | None = None, group_components: Sequence[str] = ('radial',), group_mode_rows: Sequence[ndarray] | None = None, velocity_units: str = 'km/s') → DispersionTable[source]

Create a table directly from variable-length solver outputs.

group_row(frequency_index: int, azimuth_index: int = 0) → Tuple[ndarray, ndarray][source]
group_velocity: ComplexCSR | None = None
property nsolve: int
phase_row(frequency_index: int, azimuth_index: int = 0) → Tuple[ndarray, ndarray][source]
phase_velocity: ComplexCSR
solve_row(frequency_index: int, azimuth_index: int = 0) → int[source]

Map grid indices to the frequency-major CSR row.

to_hdf5(path) → None[source]

Write schema-versioned CSR data using HDF5 compound complex values.

validate() → None[source]
velocity_units: str = 'km/s'

Complete solver output

class specd.RaggedComplexField(indptr: ndarray, values: ndarray, component_names: Tuple[str, ...], units: str = 'normalized')[source]

Bases: object

Variable-length complex samples with a fixed component dimension.

component_names: Tuple[str, ...]
indptr: ndarray
property nrow: int
row(row: int) → ndarray[source]

Return one field as a zero-copy (npoint,ncomponent) view.

units: str = 'normalized'
validate(nrow: int | None = None) → None[source]
values: ndarray
class specd.KernelTable(parameter_names: Tuple[str, ...], velocity: ndarray, propagation_q_inverse: ndarray | None = None)[source]

Bases: object

Projected kernels with shape (nmode,nparameter,ndepth).

parameter_names: Tuple[str, ...]
propagation_q_inverse: ndarray | None = None
velocity: ndarray
class specd.SolverOutput(dispersion: DispersionTable, wave_type: int, attenuation: bool, kernel_type: int, kernel_observable: str, model_depth: ndarray, sem_depth_indptr: ndarray, sem_depth_values: ndarray, eigenfunctions: RaggedComplexField, elastic_kernels: KernelTable | None = None, acoustic_kernels: KernelTable | None = None)[source]

Bases: object

Complete command-line result backed only by NumPy containers.

acoustic_kernels: KernelTable | None = None
attenuation: bool
dispersion: DispersionTable
eigenfunctions: RaggedComplexField
elastic_kernels: KernelTable | None = None
classmethod from_hdf5(path) → SolverOutput[source]

Read complete output written by a C++ or Python solver.

kernel_observable: str
kernel_type: int
model_depth: ndarray
sem_depth_indptr: ndarray
sem_depth_row(solve_row: int) → ndarray[source]

Return the physical SEM depth coordinates for one solve row.

sem_depth_values: ndarray
to_hdf5(path) → None[source]

Write the complete version-1 solver output.

validate() → None[source]
wave_type: int

Constant-Q helpers

specd.constant_q_response(freq, quality_factor, reference_frequency=1.0)[source]

Return M(omega) / M0 for storage modulus M0 at the reference.

The response uses the positive-frequency convention of SpecSWD:

s = (1 + i/Q) * (freq/reference_frequency)**alpha, alpha = 2/pi * atan(1/Q).

specd.constant_q_response_derivatives(freq, quality_factor, reference_frequency=1.0)[source]

Return s, ds/domega, ds/d(Q^-1), and the mixed derivative.

Thomson-Haskell comparison solver

class specd.THSolver(thick: ndarray, vp: ndarray, vs: ndarray, rho: ndarray, spherical: bool = False)[source]

Bases: object

compute_swd(wavetype: str, mode: int, T: ndarray) → ndarray[source]

compute dispersion (phase/group) for a give wavetype

Parameters:
  • wavetype (str) – wave type, one of [‘Rc’,’Rg’,’Lc’,’Lg’]

  • mode (int) – which mode it will return, >=0

  • T (np.ndarray) – period, in s

Returns:

cg – phase velocity (for Rc,Lc) or group velocity (Rg,Lg)

Return type:

np.ndarray