particleman package¶
Submodules¶
particleman.core module¶
Core Stockwell transform and inverse transform functions.
-
particleman.core.
get_TF_arrays
(N, Fs=0, hp=0, lp=0)[source]¶ Make the Stockwell time, frequency arrays for plotting.
- Parameters
N (int) – Number of samples in the time series.
hp (float) – high-pass point in samples (if Fs is not specified) or in Hz (if Fs is specified)
lp (float) – low-pass point in samples (if Fs is not specified) or in Hz (if Fs is specified)
Fs (float) – sampling rate in Hz
- Returns
T, F
- Return type
numpy.ndarray (complex, rank 2)
-
particleman.core.
stransform
(x, Fs=0, hp=0, lp=0, return_time_freq=False)[source]¶ Perform a Stockwell transform on a time-series.
Returns the transform (S), and time (T) and frequency (F) matrices suitable for use with the contour/contourf functions.
- Parameters
x (numpy.ndarray) – array containing time-series data
hp (float) – high-pass point in samples (if Fs is not specified) or in Hz (if Fs is specified)
lp (float) – low-pass point in samples (if Fs is not specified) or in Hz (if Fs is specified)
Fs (float) – sampling rate in Hz
return_time_freq (bool) – If True, also return the correct-sized time and frequency domain tiles.
- Returns
S (numpy.ndarray (numpy.complex128, rank 2)) – Stockwell transform (S) matrix
T, F (numpy.ndarray (float64, rank 2), optional) – Time (T) and frequency (F) matrices.
Examples
Transform a 100 Hz time series
>>> S, T, F = stransform(data, Fs=100, return_time_freq=True) >>> plt.contourf(T, F, abs(S))
References
particleman.filter module¶
Time-frequency filtering for seismic waves.
To estimate propagation azimuth for a prograde/retrograde Rayleigh wavetrain:
Make complex component s-transforms, Sn, Se, Sv
Apply phase delay to Sv for normal retrograde motion, advance for prograde motion
Convert complex transforms into MxNx2 real (“vector”) arrays
Calculate theta from theta_r and theta_l
To make a normalized inner product (NIP) filter, given azimuth
Rotate Sn, Se through theta, into radial (Sr) and transverse (St) component transforms
Calculate NIP using the vector Sr and phase-shifted vector Sv
Extract surface waves using NIP >= 0.8 (smoothed) as a filter on Sr, St, Sv, and invert to time domain. Rayleigh waves will be on the time-domain radial, Love on the time-domain transverse.
References
Meza-Fajardo, K. C., Papageorgiou, A. S., and Semblat, J. F. (2015). Identification and Extraction of Surface Waves from Three Component Seismograms Based on the Normalized Inner Product. Bulletin of the Seismological Society of America.
-
particleman.filter.
NIP
(Sr, Sv, polarization=None, eps=None)[source]¶ Get the normalized inner product of two complex MxN stockwell transforms.
- Parameters
Sr (numpy.ndarray (complex, rank 2)) – The radial and vertical component s-transforms. If the polarization argument is omitted, Sv is assumed to be phase-shifted according to the desired polarization.
Sv (numpy.ndarray (complex, rank 2)) – The radial and vertical component s-transforms. If the polarization argument is omitted, Sv is assumed to be phase-shifted according to the desired polarization.
polarization (str, optional) – If provided, the Sv will be phase-shifted according to this string before calculating the NIP. ‘retrograde’ will apply a pi/2 phase advance (1j * Sv) ‘prograde’ or ‘linear’ will apply a pi/2 phase delay (-1j * Sv)
eps (float, optional) – Tolerance for small denominator values, for numerical stability. Useful for synthetic noise-free data. Authors used 0.04.
- Returns
nip – MxN array of floats between -1 and 1.
- Return type
numpy.ndarray (rank 2)
References
Equation (16) and (26) from Meza-Fajardo et al. (2015)
-
particleman.filter.
NIP_filter
(n, e, v, fs, xpr, polarization, threshold=0.8, width=0.1, eps=None)[source]¶ Filter a 3-component seismogram based on the NIP criterion.
This is a composite convenience routine that uses sane defaults. If you want to get intermediate products, call internal routines individually.
- Parameters
n (numpy.ndarray (rank 1)) – Equal-length data arrays for North, East, and Vertical components, respectively.
e (numpy.ndarray (rank 1)) – Equal-length data arrays for North, East, and Vertical components, respectively.
v (numpy.ndarray (rank 1)) – Equal-length data arrays for North, East, and Vertical components, respectively.
fs (float) – Sampling frequency [Hz]
xpr (int) – Sense of wave propagation. -1 for westward, 1 for eastward. Try -int(np.sign(np.sin(np.radians(baz)))), unless they’re directly N-S from each other.
polarization (str) – ‘retrograde’ to extract normal retrograde Rayleigh waves ‘prograde’ to extract prograde Rayleigh waves ‘linear’ to extract Love waves
threshold (float) – The critical value (“x_r”) and width (“Delta x”) for the NIP filter (cosine) taper.
width (float) – The critical value (“x_r”) and width (“Delta x”) for the NIP filter (cosine) taper.
eps (float) – Tolerance for small NIP denominator values, for numerical stability.
- Returns
n, e, v (numpy.ndarray (rank 1)) – Filtered north, east, and vertical components.
theta (float) – Average propagation azimuth for the given polarization [degrees]. Use this angle to rotate the data to radial and transverse.
Examples
# compare filtered north, east, vertical to original >>> import obspy.signal as signal >>> nf, ef, vf, theta = NIP_filter(n, e, v, fs, xpr) >>> if theta > 180:
nip_baz = theta - 180
- else:
nip_baz = theta + 180
>>> rf, tf = signal.rotate_NE_RT(nf, ef, nip_baz) >>> r, t = signal.rotate_NE_RT(n, e, baz)
-
particleman.filter.
get_filter
(nip, polarization, threshold=None, width=0.1)[source]¶ Get an NIP-based filter that will pass waves of the specified type.
The filter is made from the NIP and cosine taper for the specified wave type. The nip and the polarization type must match.
- Parameters
nip (numpy.ndarray (real, rank 2)) – The NIP array [-1.0, 1.0]
polarization (str) – The type of polarization that was used to calculate the provided NIP. ‘retrograde’, ‘prograde’, or ‘linear’. See “NIP” function.
threshold (float) – The cosine taper critical/crossover value (“x_r”) and width (“Delta x”). If not supplied, the default for retrograde polarization is 0.8, and for prograde or linear polarization is 0.2.
width (float) – The cosine taper critical/crossover value (“x_r”) and width (“Delta x”). If not supplied, the default for retrograde polarization is 0.8, and for prograde or linear polarization is 0.2.
- Returns
The NIP-based filter array [0.0, 1.0] to multiply into the complex Stockwell arrays, before inverse transforming to the time-domain.
- Return type
numpy.ndarray (real, rank 2)
References
Equation (27) and (28) from Meza-Fajardo et al. (2015)
-
particleman.filter.
get_shift
(polarization)[source]¶ Get the appropriate pi/2 phase advance or delay for the provided polarization.
- Parameters
polarization (str, {'retrograde', 'prograde', 'linear'}) – ‘retrograde’ returns i, for a pi/2 phase advance. ‘prograde’ or ‘linear’ returns -i, for a pi/2 phase delay
- Returns
Multiply this value (i or -i) into a complex vertical S-transform to shift its phase.
- Return type
numpy.complex128
-
particleman.filter.
instantaneous_azimuth
(Sv, Sn, Se, polarization, xpr)[source]¶ Get instantaneous propagation angle [degrees], under the Rayleigh wave assumption, using the Meza-Fajardo et al. Normalized Inner Product criterion.
- Parameters
Sv (numpy.ndarray (complex, rank 2)) – The vertical, North, and East component equal-sized complex s-transforms.
Sn (numpy.ndarray (complex, rank 2)) – The vertical, North, and East component equal-sized complex s-transforms.
Se (numpy.ndarray (complex, rank 2)) – The vertical, North, and East component equal-sized complex s-transforms.
polarization (str, {'retrograde', 'prograde', 'linear'}) – ‘retrograde’ will apply a pi/2 phase advance. ‘prograde’ or ‘linear’ will apply a pi/2 phase delay
xpr (int) – Sense of propagation. 1 for eastward, -1 for westward. Try -int(np.sign(np.sin(np.radians(baz)))), unless they’re directly N-S from each other.
- Returns
az – Instantaneous Rayleigh wave propagation angle [degrees]
- Return type
numpy.ndarray (real, rank 2)
References
Equations (19), (20), and (21) from Meza-Fajardo et al. (2015)
“Let us emphatically note that if the sense of propagation of the phase under investigation is not established, prograde or retrograde motion cannot be defined without ambiguity.”
-
particleman.filter.
rotate_NE_RT
(Sn, Se, az)[source]¶ Rotate North and East s-transforms to radial and transverse, through the propagation angle.
- Parameters
Sn (numpy.ndarray (complex, rank 2)) – Complex, equal-sized s-transform arrays, for North and East components, respectively.
Se (numpy.ndarray (complex, rank 2)) – Complex, equal-sized s-transform arrays, for North and East components, respectively.
az (float) – Rotation angle [degrees].
- Returns
Sr, St – Complex s-transform arrays for radial and transverse components, respectively.
- Return type
numpy.ndarray (rank 2)
References
Equation (17) from Meta-Fajardo et al. (2015)
-
particleman.filter.
scalar_azimuth
(e, n, vhat)[source]¶ Time domain estimation the scalar/average azimuth, in degrees.
References
Equations (10) and (12) from Meza-Fajardo et al. (2015)
“If the extracted signal is composed of more than one dispersive wave propagating in distinct, albeit similar, directions, then, equations (10)–(12) should be applied independently to each one of them. By inspecting the Stockwell transform of the signal, the analyst can observe if there are several wavetrains.”
-
particleman.filter.
shift_phase
(Sv, polarization)[source]¶ Phase-shift an s-transform by the appropriate phase shift for prograde/retrograde motion.
Shift is done on a complex MxN array by multiplication with either i or -i (imaginary unit). This is mostly a reference for how to do/interpret phase shifts, as it’s such a simple thing to do outside of a function.
- Parameters
Sv (numpy.ndarray (complex, rank 2)) –
polarization (str, {'retrograde', 'prograde', 'linear'}) – ‘retrograde’ will apply a pi/2 phase advance (normal Rayleigh waves) ‘prograde’ or ‘linear’ will apply a pi/2 phase delay
- Returns
- Return type
numpy.ndarray (real, rank 2)
References
Pages 5 and 10 from Meta-Fajardo et al. (2015)
-
particleman.filter.
xpr
(az)[source]¶ Get the Meza-Fajardo “xpr” sense-of-propagation of wavefield. propagation azimuth.
- Parameters
az (int or float) – Propagation direction in degrees.
- Returns
1 for eastward propagation
-1 for westward
Notes
If the azimuth is 0 or 180, polarization type may be ambiguous.
particleman.plotting module¶
Plotting functions for Stockwell transforms and normalized inner-product (NIP) filtering.
These plotting routines, particularly tile_comparison and NIP_filter_plot, are useful to see how much surface wave energy is in a packet, or how much off-great-circle propagation there is.
These functions plot a number of configurations of “tiles.” Each tile consists of the Stockwell transform on top and an aligned time-series waveform below. The transform may have a hatching overlay that would normally correspond to a NIP filter, and the time-series axis may have a reference (gray) trace overlayed, which normally corresponds to the unfiltered trace.
## Channel nomenclature:
`
[nevrt][sd][f]
`
n : north component
e : east
v : vertical
s : scalar rotation (great circle)
d : dynamic rotation (NIP estimate)
f : NIP filtered
-
particleman.plotting.
NIP_filter_plots
(T, F, theta, fs, Sr, St, Sv, r, t, v, rf, tf=None, vf=None, arrivals=None, flim=None, hatch=None, hatchlim=None, fig=None)[source]¶ - def NIP_filter_plots(T, F, theta, fs, Sr, St, Sv, rf, r, vf, v, t, tf=None,
Quad plot of NIP, and 3 tiles of Stockwell transform with NIP filter hatch and filtered+unfiltered time-series for each component.
- T, F, theta: numpy.ndarray (ndim 2)
Time, frequency, instantaneous azimuth tiles.
- fsfloat
Sampling rate of underlying time-series data.
- Sr, St, Svnumpy.ndarray (ndim 2, complex)
Stockwell transform of the radial, transverse, and vertical component data.
- r, t, v: numpy.ndarray (ndim 1)
Unfiltered radial, transverse, and vertical component time-series.
- rf, tf, vfnumpy.ndarray (ndim 1)
NIP-filtered radial, transverse, and vertical component time-series.
- arrivalssequence of (str, float) 2-tuples
Sequence of arrivals to plot, of the form (label, time_in_seconds)
- flimtuple
Frequency limits as (fmin, fmax) 2-tuple, in Hz.
- hatchnumpy.ndarray (ndim 2)
Optional tile used for cross-hatch visual mask.
- hatchlimtuple
Hatch range used to display mask. 2-tuple of floats (hmin, hmax).
fig : matplotlib.Figure
- tileslist
List of two-tuples of axes objects (axis_top, axis_bottom) of each tile, clockwise from top-left. Can be unpacked to get all axes as follows:
>>> tiles = NIP_filter_plots(...) >>> (ax11, ax12), (ax21, ax22), (ax31, ax32), (ax41, ax42) = tiles
-
particleman.plotting.
check_filters
(T, F, Sv, Srs, Sts, vsf, rsf, ts, arrivals, flim, clim, dlim, xlim, hatch=None, hatchlim=None, fig=None)[source]¶ - Parameters
T (numpy.ndarray (ndim 2)) – The time and freqency domain tiles/grids.
F (numpy.ndarray (ndim 2)) – The time and freqency domain tiles/grids.
Sv (numpy.ndarray (ndim 2)) – The vertical, scalar-rotated radial, and scalar-rotated transverse Stockwell transform tiles.
Srs (numpy.ndarray (ndim 2)) – The vertical, scalar-rotated radial, and scalar-rotated transverse Stockwell transform tiles.
Sts (numpy.ndarray (ndim 2)) – The vertical, scalar-rotated radial, and scalar-rotated transverse Stockwell transform tiles.
vsf (numpy.ndarray (ndim 1)) – The Stockwell NIP-filtered vertical and radial, and transverse time-series vectors.
rsf (numpy.ndarray (ndim 1)) – The Stockwell NIP-filtered vertical and radial, and transverse time-series vectors.
ts (numpy.ndarray (ndim 1)) – The Stockwell NIP-filtered vertical and radial, and transverse time-series vectors.
arrivals (sequence of (str, float) 2-tuples) – Sequence of arrivals to plot, of the form (label, time_in_seconds)
dlim (2-tuple of floats) – Limits on the time-series amplitudes (y axis limits).
hatch (numpy.ndarray (ndim 2)) – Optional tile used for hatch mask.
hatchlim (tuple) – Hatch range used to display mask. 2-tuple of floats (hmin, hmax).
fig (matplotlib.Figure) –
- Returns
- Return type
matplotlib.Figure
-
particleman.plotting.
compare_waveforms
(v, vsf, rs, rsf, ts, arrivals)[source]¶ Compare the static and dynamically filtered waveforms.
A 3-panel waveform plot of 3 components. Unfiltered waves are in gray, filtered are overplotted in black.
- Parameters
v (numpy.ndarray (rank 1)) – Unfiltered and static-rotated filtered vertical waveform.
vsf (numpy.ndarray (rank 1)) – Unfiltered and static-rotated filtered vertical waveform.
rs (numpy.ndarray (rank 1)) – Unfiltered and static-rotated filtered radial waveform.
rsf (numpy.ndarray (rank 1)) – Unfiltered and static-rotated filtered radial waveform.
ts (numpy.ndarray (rank 1)) – Unfiltered transverse waveform.
-
particleman.plotting.
make_tiles
(fig, gs0, full=None)[source]¶ Give a list of (ax_top, ax_bottom) axis tuples for each SubPlotSpec in gs0.
- fulllist
Integer subplotspec numbers for which the ax_top is to take up the whole tile, so no ax_bottom is to be created. Returns these tiles’ axis handles as (ax_top, None).
-
particleman.plotting.
plot_NIP
(T, F, nips, fs=1.0, flim=None, fig=None, ax=None)[source]¶ Plot the normalized inner product tile.
- Parameters
T (numpy.ndarray (ndim 2)) – Time, frequency, normalized inner-product tiles.
F (numpy.ndarray (ndim 2)) – Time, frequency, normalized inner-product tiles.
nips (numpy.ndarray (ndim 2)) – Time, frequency, normalized inner-product tiles.
fs (float) – Sampling frequency of the underlying time-series data.
flim (tuple) – Frequency limits as (fmin, fmax) 2-tuple, in Hz.
- Returns
- Return type
matplotlib.Figure
-
particleman.plotting.
plot_arrivals
(ax, arrivals, dmin, dmax)[source]¶ - arrivalsdict
are a dict of {name: seconds}.
- dmin, dmaxfloat
y value in axis “ax” at which labels are plotted.
-
particleman.plotting.
plot_image
(T, F, C, hatch=None, hatchlim=None, flim=None, clim=None, fig=None, ax=None, cmap=None, alpha=None)[source]¶ Plot a fime-frequency image, optionally with a hatched mask.
- T, F, Cnumpy.ndarray (ndim 2)
Time and frequency domain arrays, and data arrays.
- hatchnumpy.ndarray (rank 2)
Optional array mask for hatching or for opacity.
- hatchlimfloat
Optional hatch value cutoff for masking, above which masking is not done. If hatch is provided but hatchlim is not, hatch will be used as an opacity mask, and it values are assumed to be between 0 and 1.
- Returns
- Return type
matplotlib.collections.QuadMesh from pcolormesh
-
particleman.plotting.
plot_instantaneous_azimuth
(T, F, theta, fs=1.0, flim=None, dlim=None, clim=None, fig=None, ax=None)[source]¶ Plot the instantanous azimuth TF tile using imshow.
- Parameters
T (numpy.ndarray (ndim 2)) – Time [sec], frequency [Hz], and instantaneous azimuth calculated by stockwell.filter.instantanous_azimuth
F (numpy.ndarray (ndim 2)) – Time [sec], frequency [Hz], and instantaneous azimuth calculated by stockwell.filter.instantanous_azimuth
theta (numpy.ndarray (ndim 2)) – Time [sec], frequency [Hz], and instantaneous azimuth calculated by stockwell.filter.instantanous_azimuth
fs (float) – Sampling rate of data used.
flim (tuple (min, max)) – Optional frequency [Hz], time [sec], or color min/max limits for plots.
dlim (tuple (min, max)) – Optional frequency [Hz], time [sec], or color min/max limits for plots.
clim (tuple (min, max)) – Optional frequency [Hz], time [sec], or color min/max limits for plots.
fig (matplotlib.Figure instance) –
ax (matplotlib.axis.Axis instance) –
- Returns
- Return type
matplotlib.Figure
-
particleman.plotting.
plot_tile
(fig, ax1, T, F, S, ax2, d1, label1, color1='k', d2=None, label2=None, arrivals=None, flim=None, clim=None, hatch=None, hatchlim=None, dlim=None, amp_fmt='%.2e', cmap=None, alpha=None)[source]¶ Plot time-frequency pcolormesh tiles above time-aligned aligned time-series.
- Parameters
fig (matplotlib.Figure) –
ax1 (matplotlib.axis.Axis) – Axis for time-frequency pcolormesh tile and optional hatching.
ax2 (matplotlib.axis.Axis) – Axis for time-series plot.
T (numpy.ndarray (ndim 2)) – Time, frequency, S-transform tiles from stockwell.stransform
F (numpy.ndarray (ndim 2)) – Time, frequency, S-transform tiles from stockwell.stransform
S (numpy.ndarray (ndim 2)) – Time, frequency, S-transform tiles from stockwell.stransform
d1 (numpy.ndarray (ndim 1)) – Time-series, plotted black. Optional d2 plotted gray. These need to be registered in time to T.
d2 (numpy.ndarray (ndim 1)) – Time-series, plotted black. Optional d2 plotted gray. These need to be registered in time to T.
color1 (str) – Color of plotted d1 line.
label1 (str) – Time-series legend label strings.
label2 (str) – Time-series legend label strings.
arrivals (dict) – Sequence of arrivals to plot, of the form {label: time_in_seconds, …}
dlim (2-tuple of floats) – Limits on the time-series amplitudes (y axis limits).
hatch (numpy.ndarray (ndim 2)) – Optional tile used for hatch mask.
hatchlim (tuple) – Hatch range used to display mask. 2-tuple of floats (hmin, hmax).
amp_fmt (str) – Matplotlib format string used for amplitudes in colorbars and axes.
cmap (matplotlib.colors.Colormap) –
alpha (float) – Optionally, use a white transparency mask for overlying the hatch, with the given alpha value.
- Returns
The ax1 image from pcolormesh.
- Return type
matplotlib.collections.QuadMesh
Examples
# filtered versus unfiltered radial, and set color limits >>> plot_tile(fig, ax21, T, F, Srs, ax22, rs, ‘unfiltered’, rsf, ‘NIP filtered’,
arrivals=arrivals, flim=(0.0, fmax), clim=(0.0, 5e-5), hatch=sfilt, hatchlim=(0.0, 0.8))
# scalar versus dynamic rotated radial >>> plot_tile(fig, ax21, T, F, Srs, ax22, rs, ‘scalar’, rd, ‘dynamic’, arrivals
flim=(0.0, fmax), clim=(0.0, 5e-5), hatch=dfilt, hatchlim=(0.0, 0.8))
-
particleman.plotting.
tile_comparison
(T, F, Sv, Srs, Srd, Sts, Std, v, rs, rd, ts, td, arrivals, flim, clim, dlim, hatch=None, hatchlim=None, fig=None, xlim=None)[source]¶ Make a 6-panel side-by-side comparison of tiles, such as scalar versus dynamic rotations.
- Sv, Srs, Srd, Sts, Stdnumpy.ndarray (ndim 2)
The vertical, radial-scalar, radial-dynamic, transverse-scalar, and transverse-dynamic stockwell transforms.
- v, rs, rd, ts, tdnumpy.ndarray (ndim 1)
The corresponding vertical, radial-scalar, radial-dynamic, transverse-scalar, and transverse-dynamic time-series vectors.
- arrivalssequence of (str, float) 2-tuples
Sequence of arrivals to plot, of the form (label, time_in_seconds)
- flim, clim, dlim, xlimtuple
Frequency, stockwell amplitude, time-series amplitude, and time-series time limits of display. 2-tuples of (min, max) floats.
- hatchnumpy.ndarray (ndim 2)
Optional tile used for hatch mask.
- hatchlimtuple
Hatch range used to display mask. 2-tuple of floats (hmin, hmax).
- Returns
- Return type
matplotlib.Figure
particleman.st module¶
ctypes interface to st.c
-
particleman.st.
st
(data, lo=None, hi=None)[source]¶ st(x[, lo, hi]) returns the 2d, complex Stockwell transform of the real array x. If lo and hi are specified, only those frequencies (rows) are returned; lo and hi default to 0 and n/2, resp., where n is the length of x.
Stockwell transform of the real array data. The number of time points need not be a power of two. The lo and hi arguments specify the range of frequencies to return, in Hz. If they are both zero, they default to lo = 0 and hi = len / 2. The result is returned in the complex array result, which must be preallocated, with n rows and len columns, where n is hi - lo + 1. For the default values of lo and hi, n is len / 2 + 1.
Module contents¶
Stockwell transform and its inverse.