GroundMotion#

class sgsim.GroundMotion(npts, dt, ac, vel, disp, tag=None)[source]#

Bases: object

Container 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:

GroundMotion

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

Record

Underlying 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:

GroundMotion

Raises:

ValueError – If indices are out of bounds (start_index < 0 or end_index > npts).

See also

trim_by_slice

Trim using Python slice notation.

trim_by_energy

Trim 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:

GroundMotion

Raises:

TypeError – If slicer is not a slice object.

See also

trim_by_index

Trim 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:

GroundMotion

Raises:

ValueError – If fractions are not in [0, 1] or start >= end.

See also

ce

Cumulative energy property.

trim_by_amplitude

Trim 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:

GroundMotion

See also

trim_by_energy

Alternative trimming based on energy content.

pga

Peak 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:

GroundMotion

See also

butterworth_filter

Frequency 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:

GroundMotion

Raises:

ValueError – If low_freq >= high_freq or frequencies exceed Nyquist limit.

See also

taper

Recommended before filtering to reduce edge effects.

fas

Fourier amplitude spectrum for frequency content inspection.

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:

GroundMotion

See also

butterworth_filter

Alternative 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:

GroundMotion

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.

See also

vsi

Velocity spectrum intensity.

asi

Acceleration spectrum intensity.

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.

See also

list_IMs

List all available IMs.

to_csv

Export computed IMs to file.

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_measures

Underlying 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_fit

GOF calculation method.

relative_error

Relative 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

See also

asi

Acceleration spectrum intensity.

dsi

Displacement spectrum intensity.

where

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

See also

vsi

Velocity spectrum intensity.

dsi

Displacement spectrum intensity.

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

See also

vsi

Velocity spectrum intensity.

asi

Acceleration spectrum intensity.

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

fas

Fourier amplitude spectrum.

property fas[source]#

Fourier amplitude spectrum of acceleration.

Returns:

Amplitude values at frequencies given by freq property.

Return type:

ndarray

See also

freq

Corresponding frequency array.

fps

Fourier phase spectrum.

fas_vel

FAS of velocity.

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

See also

fas

FAS of acceleration.

fas_disp

FAS of displacement.

property fas_disp[source]#

Fourier amplitude spectrum of displacement.

Returns:

Amplitude values at frequencies given by freq property.

Return type:

ndarray

See also

fas

FAS of acceleration.

fas_vel

FAS of velocity.

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

fas

Fourier 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_energy

Trim based on energy range.

cav

Cumulative absolute velocity.

property pga[source]#

Peak ground acceleration.

Maximum absolute acceleration value in record.

Returns:

PGA value.

Return type:

float

See also

pgv

Peak ground velocity.

pgd

Peak ground displacement.

Examples

>>> gm.pga
0.521
property pgv[source]#

Peak ground velocity.

Maximum absolute velocity value in record.

Returns:

PGV value.

Return type:

float

See also

pga

Peak ground acceleration.

pgd

Peak ground displacement.

property pgd[source]#

Peak ground displacement.

Maximum absolute displacement value in record.

Returns:

PGD value.

Return type:

float

See also

pga

Peak ground acceleration.

pgv

Peak ground velocity.

property cav[source]#

Cumulative absolute velocity.

Integral of absolute acceleration over time, damage potential indicator.

Returns:

CAV value.

Return type:

float

See also

ce

Cumulative 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

dsi

Displacement spectrum intensity.

vsi

Velocity spectrum intensity.

asi

Acceleration spectrum intensity.

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

See also

zc_vel

Zero-crossing of velocity.

le_ac

Local extrema measure.

property zc_vel[source]#

Zero-crossing of velocity.

Returns:

Cumulative count of zero-crossing.

Return type:

ndarray

See also

zc_ac

Zero-crossing of acceleration.

property zc_disp[source]#

Zero-crossing of displacement.

Returns:

Cumulative count of zero-crossing.

Return type:

ndarray

See also

zc_vel

Zero-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

See also

le_vel

Local extrema of velocity.

le_disp

Local extrema of displacement.

pga

Peak ground acceleration.

property le_vel[source]#

Mean local extrema of velocity.

Returns:

Cumulative number of local extrema.

Return type:

ndarray

See also

le_ac

Local extrema of acceleration.

pgv

Peak ground velocity.

property le_disp[source]#

Mean local extrema of displacement.

Returns:

Cumulative number of local extrema.

Return type:

ndarray

See also

le_vel

Local extrema of velocity.

pgd

Peak ground displacement.