GroundMotion#
- class sgsim.GroundMotion(npts, dt, ac, vel, disp, tag=None)[source]#
Bases:
objectContainer for ground motion data and related operations.
This class stores acceleration, velocity, and displacement time series along with derived intensity measures. All transformation methods return new instances rather than modifying in place.
- Parameters:
npts (int) – Number of time points in the record.
dt (float) – Time step interval in seconds.
ac (ndarray) – Acceleration time series.
vel (ndarray) – Velocity time series.
disp (ndarray) – Displacement time series.
tag (str, optional) – Identifier for the ground motion record (default is None).
Notes
Ground motion instances should be treated as immutable. Direct modification of npts, dt, ac, vel, or disp may lead to inconsistent cached properties.
Examples
Load from file:
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> gm.pga 0.45
Create from arrays:
>>> import numpy as np >>> ac = np.random.randn(1000) >>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=ac) >>> gm_trimmed = gm.trim_by_energy((0.05, 0.95)) >>> gm_trimmed.npts 900
- classmethod load_from(tag=None, **kwargs)[source]#
Load ground motion from file or array.
Factory method for creating GroundMotion instances from various sources including seismic database formats (NGA, ESM) or direct array input.
- Parameters:
source (str) – Data source format. Options: - ‘NGA’: PEER NGA database format - ‘ESM’: Engineering Strong Motion database - ‘COL’: Column-based text format - ‘RAW’: Raw binary format - ‘COR’: Corrected format - ‘array’: Direct NumPy array input
tag (str, optional) – Record identifier for tracking (default is None).
**kwargs (dict) – Source-specific arguments.
- Returns:
New ground motion instance.
- Return type:
- Raises:
ValueError – If required parameters are missing for the specified source.
FileNotFoundError – If file does not exist for file-based sources.
Notes
For kwargs details, refer to Record documentation.
See also
RecordUnderlying file reading implementation.
Examples
Load from NGA file:
>>> gm = GroundMotion.load_from(source='NGA', file='RSN123.at2', tag='RSN123') >>> gm.pga 0.521
Create from array:
>>> import numpy as np >>> ac = np.sin(2 * np.pi * np.arange(1000) * 0.01) >>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=ac, tag='synthetic') >>> gm.npts 1000
- classmethod list_IMs()[source]#
View the available intensity measure (IM) and attributes registry.
- Returns:
dict: A copy of the available IM registry.
- trim_by_index(start_index, end_index)[source]#
Trim ground motion by index range.
Extracts a subset of the time series between specified indices, creating a new GroundMotion instance with reduced duration.
- Parameters:
start_index (int) – Starting index (inclusive).
end_index (int) – Ending index (exclusive).
- Returns:
New instance with trimmed time series.
- Return type:
- Raises:
ValueError – If indices are out of bounds (start_index < 0 or end_index > npts).
See also
trim_by_sliceTrim using Python slice notation.
trim_by_energyTrim based on cumulative energy range.
Examples
>>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=np.random.randn(1000)) >>> gm_trimmed = gm.trim_by_index(100, 900) >>> gm_trimmed.npts 800
- trim_by_slice(slicer)[source]#
Trim ground motion using Python slice object.
Provides flexible slicing similar to NumPy array indexing with support for negative indices and step values.
- Parameters:
slicer (slice) – Python slice object (e.g., slice(100, 500, 2)).
- Returns:
New instance with sliced time series.
- Return type:
- Raises:
TypeError – If slicer is not a slice object.
See also
trim_by_indexTrim with explicit start/end indices.
Examples
>>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=np.random.randn(1000)) >>> gm_trimmed = gm.trim_by_slice(slice(100, 900)) >>> gm_trimmed.npts 800
Every other point:
>>> gm_decimated = gm.trim_by_slice(slice(None, None, 2)) >>> gm_decimated.npts 500
- trim_by_energy(energy_range)[source]#
Trim ground motion to retain specified cumulative energy range.
Identifies time window containing the target energy range (e.g., 5%-95%) based on cumulative energy of acceleration. Useful for focusing on significant motion and removing weak pre/post-event portions.
- Parameters:
energy_range (tuple of float) – (start_fraction, end_fraction) where fractions are in [0, 1]. Example: (0.05, 0.95) retains central 90% of energy.
- Returns:
New instance trimmed to energy range.
- Return type:
- Raises:
ValueError – If fractions are not in [0, 1] or start >= end.
See also
ceCumulative energy property.
trim_by_amplitudeTrim based on amplitude threshold.
Notes
This method is particularly useful for removing weak motion at the beginning and end of records, which can affect baseline correction and filtering operations.
Examples
Retain central 90% of energy:
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> gm_trimmed = gm.trim_by_energy((0.05, 0.95)) >>> gm_trimmed.npts < gm.npts True
- trim_by_amplitude(threshold)[source]#
Trim ground motion based on acceleration amplitude threshold.
Identifies the time window where acceleration exceeds the specified threshold, removing weak motion at start and end.
- Parameters:
threshold (float) – Amplitude threshold in same units as acceleration (typically g).
- Returns:
New instance trimmed to significant motion window.
- Return type:
See also
trim_by_energyAlternative trimming based on energy content.
pgaPeak ground acceleration.
Notes
Common practice is to use threshold = 0.05 * PGA for removing insignificant portions while preserving strong motion window.
Examples
>>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=np.random.randn(1000)) >>> threshold = 0.05 * gm.pga >>> gm_trimmed = gm.trim_by_amplitude(threshold)
- taper(alpha=0.05)[source]#
Apply Tukey window tapering to ground motion.
Smoothly tapers the beginning and end of the time series to zero using a Tukey (tapered cosine) window. Reduces spectral leakage in frequency domain analysis and prevents edge effects in filtering.
- Parameters:
alpha (float, optional) – Taper fraction in [0, 1]. Fraction of window inside cosine tapered region. - 0: Rectangular window (no tapering) - 1: Hann window (full taper) - 0.05: Default, tapers 5% at each end (default is 0.05).
- Returns:
New instance with tapered acceleration.
- Return type:
See also
butterworth_filterFrequency domain filtering.
Notes
Tapering is recommended before applying Fourier transforms or filters to minimize edge discontinuities.
Examples
Apply 5% taper (default):
>>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=np.random.randn(1000)) >>> gm_tapered = gm.taper()
Apply 10% taper:
>>> gm_tapered = gm.taper(alpha=0.10)
- butterworth_filter(bandpass_freqs, order=4)[source]#
Apply Butterworth bandpass filter using second-order sections (SOS).
Zero-phase Butterworth filter for frequency content selection without introducing phase distortion. Uses SOS format for improved numerical stability compared to transfer function representation.
- Parameters:
bandpass_freqs (tuple of float) – (low_freq, high_freq) in Hz. Defines passband range.
order (int, optional) – Filter order controlling steepness of rolloff (default is 4). Higher orders give sharper cutoffs but may introduce instability.
- Returns:
New instance with filtered acceleration.
- Return type:
- Raises:
ValueError – If low_freq >= high_freq or frequencies exceed Nyquist limit.
See also
Notes
The filter is applied using scipy.signal.butter with second-order sections (SOS) format via sosfilt for improved numerical stability. This approach avoids numerical issues that can occur with high-order filters in transfer function format. Velocity and displacement are recomputed from filtered acceleration.
High-frequency cutoff is automatically limited to 99% of Nyquist frequency to prevent aliasing issues.
Examples
Apply 0.1-25 Hz bandpass:
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> gm_filtered = gm.butterworth_filter((0.1, 25.0), order=4)
High-pass filter above 0.5 Hz:
>>> gm_highpass = gm.butterworth_filter((0.5, 50.0))
- baseline_correction(degree=1)[source]#
Apply polynomial baseline correction.
Removes long-period drift by fitting and subtracting a polynomial trend from acceleration. Common preprocessing step for integrating to velocity and displacement.
- Parameters:
degree (int, optional) – Polynomial degree for trend fitting (default is 1). - 0: Remove mean (DC offset) - 1: Remove linear trend - 2: Remove quadratic trend
- Returns:
New instance with corrected acceleration.
- Return type:
See also
butterworth_filterAlternative approach using high-pass filtering.
Notes
Baseline correction is essential when acceleration records show velocity or displacement drift after integration. Linear correction (degree=1) is most common in practice.
Examples
Remove linear trend:
>>> gm = GroundMotion.load_from(source='array', dt=0.01, ac=data) >>> gm_corrected = gm.baseline_correction(degree=1)
Remove mean only:
>>> gm_demeaned = gm.baseline_correction(degree=0)
- resample(dt)[source]#
Resample to new time step using Fourier method.
Changes time step by resampling in frequency domain, preserving frequency content up to new Nyquist frequency.
- Parameters:
dt (float) – New time step in seconds.
- Returns:
New instance with resampled time step.
- Return type:
- Raises:
ValueError – If dt <= 0.
Notes
Uses FFT-based resampling which preserves frequency content accurately but may introduce artifacts if new_dt is much larger than original. For upsampling (smaller dt), consider interpolation methods instead.
Examples
Downsample from 0.005s to 0.01s:
>>> gm = GroundMotion.load_from(source='array', dt=0.005, ac=data) >>> gm_resampled = gm.resample(dt=0.01) >>> gm_resampled.dt 0.01
- response_spectra(periods, damping=0.05)[source]#
Calculate response spectra for given periods and damping.
Computes spectral displacement (Sd), velocity (Sv), and acceleration (Sa) for elastic single-degree-of-freedom oscillators.
- Parameters:
periods (ndarray) – Array of natural periods in seconds.
damping (float, optional) – Damping ratio (default is 0.05 for 5% damping).
- Returns:
sd (ndarray) – Spectral displacement in cm.
sv (ndarray) – Spectral velocity in cm/s.
sa (ndarray) – Spectral acceleration in g.
Notes
Response spectra are computed using Nigam-Jennings method with numerical integration. Results represent peak absolute response of linear oscillators.
Examples
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> periods = np.logspace(-2, 1, 50) # 0.01 to 10 seconds >>> sd, sv, sa = gm.response_spectra(periods, damping=0.05) >>> sa_at_1s = sa[np.argmin(np.abs(periods - 1.0))]
- compute_intensity_measures(ims, periods=None)[source]#
Compute selected intensity measures.
Batch computation of multiple IMs with optimized calculation of spectral quantities.
- Parameters:
ims (list of str) – IM names to compute (e.g., [‘pga’, ‘sa’, ‘cav’]). Use list_IMs() for available options.
periods (ndarray, optional) – Periods for spectral IMs (sa, sv, sd). Required if any spectral IM requested.
- Returns:
Dictionary with IM names as keys. Spectral IMs have keys like ‘sa_0.200’. Values are floats (single record) or arrays (multiple records).
- Return type:
dict
- Raises:
ValueError – If periods not provided when spectral IMs requested.
AttributeError – If invalid IM name specified.
Examples
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> ims = gm.compute_intensity_measures(['pga', 'pgv', 'cav']) >>> ims['pga'] 0.521
With spectral quantities:
>>> periods = np.array([0.2, 0.5, 1.0]) >>> ims = gm.compute_intensity_measures(['pga', 'sa'], periods=periods) >>> ims['sa_0.200'] 0.842
- to_csv(filename, ims, periods=None)[source]#
Export intensity measures to CSV file.
Writes computed IMs to comma-separated values format suitable for further analysis or database storage.
- Parameters:
filename (str) – Output file path.
ims (list of str) – IM names to export.
periods (ndarray, optional) – Periods for spectral IMs.
- Raises:
ValueError – If periods not provided when spectral IMs requested.
IOError – If file cannot be written.
See also
compute_intensity_measuresUnderlying computation method.
Examples
>>> gm = GroundMotion.load_from(source='NGA', file='record.at2') >>> periods = np.array([0.2, 0.5, 1.0, 2.0]) >>> gm.to_csv('output.csv', ims=['pga', 'pgv', 'sa'], periods=periods)
- compare(other, ims, periods=None, method='gof')[source]#
Compare with another ground motion using goodness-of-fit metrics.
Quantifies similarity between this ground motion and a target/model using specified intensity measures.
- Parameters:
other (GroundMotion) – Target ground motion for comparison.
ims (list of str) – IM names to compare.
periods (ndarray, optional) – Periods for spectral IMs.
method (str, optional) – Comparison metric: ‘gof’ (goodness of fit) or ‘re’ (relative error). Default is ‘gof’.
- Returns:
Comparison scores for each IM. Lower is better for ‘gof’, closer to 0 is better for ‘re’.
- Return type:
dict
- Raises:
ValueError – If method is not recognized.
See also
goodness_of_fitGOF calculation method.
relative_errorRelative error calculation.
Notes
Goodness-of-fit (GOF) metric from Anderson (2004) combines bias and variance into single score. Values < 1 indicate good agreement.
Examples
>>> target = GroundMotion.load_from(source='NGA', file='target.at2') >>> synthetic = GroundMotion.load_from(source='array', dt=0.01, ac=simulated) >>> scores = synthetic.compare(target, ims=['pga', 'pgv', 'sa'], ... periods=np.array([0.2, 1.0, 2.0])) >>> scores['pga'] 0.15
- property vsi#
Velocity spectrum intensity (0.1-2.5s range).
Integral of pseudo-velocity response spectrum over period range 0.1-2.5 seconds with 5% damping. Correlates with damage potential.
- Returns:
VSI value.
- Return type:
float
- property asi#
Acceleration spectrum intensity (0.1-2.5s range).
Integral of acceleration response spectrum over period range 0.1-2.5 seconds with 5% damping.
- Returns:
ASI value.
- Return type:
float
- property dsi#
Displacement spectrum intensity (0.1-2.5s range).
Integral of displacement response spectrum over period range 0.1-2.5 seconds with 5% damping.
- Returns:
DSI value.
- Return type:
float
- property t[source]#
Time array corresponding to recorded points.
- Returns:
Time values from 0 to (npts-1)*dt.
- Return type:
ndarray
- property freq[source]#
Frequency array for Fourier transform.
- Returns:
Frequencies from 0 to Nyquist frequency.
- Return type:
ndarray
See also
fasFourier amplitude spectrum.
- property fas[source]#
Fourier amplitude spectrum of acceleration.
- Returns:
Amplitude values at frequencies given by freq property.
- Return type:
ndarray
Notes
Single-sided spectrum (positive frequencies only).
- property fas_vel[source]#
Fourier amplitude spectrum of velocity.
- Returns:
Amplitude values at frequencies given by freq property.
- Return type:
ndarray
- property fas_disp[source]#
Fourier amplitude spectrum of displacement.
- Returns:
Amplitude values at frequencies given by freq property.
- Return type:
ndarray
- property fps[source]#
Fourier phase spectrum of acceleration (unwrapped).
Phase angle of Fourier transform with unwrapping to ensure continuity across -π to π boundaries.
- Returns:
Unwrapped phase values in radians.
- Return type:
ndarray
See also
fasFourier amplitude spectrum.
Notes
Phase unwrapping removes 2π discontinuities using numpy.unwrap, essential for phase velocity analysis and signal reconstruction.
- property ce[source]#
Cumulative energy of acceleration time series.
Running integral of squared acceleration, representing energy accumulation over time (Arias intensity concept).
- Returns:
Cumulative energy at each time point.
- Return type:
ndarray
See also
trim_by_energyTrim based on energy range.
cavCumulative absolute velocity.
- property pga[source]#
Peak ground acceleration.
Maximum absolute acceleration value in record.
- Returns:
PGA value.
- Return type:
float
Examples
>>> gm.pga 0.521
- property pgv[source]#
Peak ground velocity.
Maximum absolute velocity value in record.
- Returns:
PGV value.
- Return type:
float
- property pgd[source]#
Peak ground displacement.
Maximum absolute displacement value in record.
- Returns:
PGD value.
- Return type:
float
- property cav[source]#
Cumulative absolute velocity.
Integral of absolute acceleration over time, damage potential indicator.
- Returns:
CAV value.
- Return type:
float
See also
ceCumulative energy.
Notes
Computed as:
\[CAV = \int_0^T |a(t)| dt\]
- property spectrum_intensity[source]#
Spectrum intensities (Sd, Sv, Sa) over 0.1-2.5s period range.
Internal property computing all three spectrum intensity types simultaneously with 5% damping.
- Returns:
(dsi, vsi, asi) values.
- Return type:
tuple of float
See also
Notes
Uses 0.05s period increment for numerical integration.
- property zc_ac[source]#
Zero-crossing of acceleration.
Cumulative number of sign changes in acceleration time series, related to dominant frequency content.
- Returns:
Cumulative count of zero-crossing.
- Return type:
ndarray
- property zc_vel[source]#
Zero-crossing of velocity.
- Returns:
Cumulative count of zero-crossing.
- Return type:
ndarray
See also
zc_acZero-crossing of acceleration.
- property zc_disp[source]#
Zero-crossing of displacement.
- Returns:
Cumulative count of zero-crossing.
- Return type:
ndarray
See also
zc_velZero-crossing of velocity.
- property pmnm_ac[source]#
Positive-minima to negative-maxima of acceleration.
- Returns:
Cumulative number of positive valley and negative peaks.
- Return type:
ndarray
- property pmnm_vel[source]#
Positive-minima to negative-maxima ratio of velocity.
- Returns:
Cumulative number of positive valley and negative peaks.
- Return type:
ndarray
- property pmnm_disp[source]#
Positive-minima to negative-maxima ratio of displacement.
- Returns:
Cumulative number of positive valley and negative peaks.
- Return type:
ndarray
- property le_ac[source]#
Mean local extrema of acceleration.
Average number of peaks and valleys in acceleration time series.
- Returns:
Cumulative number of local extrema.
- Return type:
ndarray