Skip to content

ncirrito/scarp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

109 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SCaRP - Scripps Coastal Erosion and Nearshore Processes

Python translation of MATLAB coastal oceanography research code for analyzing wave runup, beach erosion/accretion, and nearshore bathymetric changes at Torrey Pines, California.

Overview

SCaRP processes data from:

  • Drone LiDAR (100 Hz) - High-frequency surface elevation measurements
  • Truck-mounted LiDAR - Mobile scanning along the beach
  • Paros pressure sensors (2 Hz) - Subsurface wave measurements

Study Site: Torrey Pines, California (NOAA Station 9410230) Deployment Period: December 2019 - March 2020 Original MATLAB Code: Julia Fiedler (jfiedler@ucsd.edu)

Installation

# Clone the repository
git clone https://github.com/your-username/scarp.git
cd scarp

# Option 1: Use existing conda environment with numpy/scipy
conda activate coastseg  # or any env with numpy/scipy

# Option 2: Create new environment
conda create -n scarp python=3.10 numpy scipy
conda activate scarp

# Install optional dependencies
pip install laspy h5py

# Install the package (from the code directory)
cd code
pip install -e .

Dependencies

  • numpy - Numerical computing
  • scipy - Scientific computing (signal processing, interpolation, optimization)
  • laspy (optional) - LAS file reading
  • h5py (optional) - HDF5/MATLAB v7.3 file support
  • matplotlib (optional) - Visualization

Testing

Run the test suite to verify the installation:

cd code
python test_scarp.py

Expected output:

============================================================
  Test Summary
============================================================
  [PASS] Imports
  [PASS] MAT I/O
  [PASS] Spectral Analysis
  [PASS] Wave Dispersion
  [PASS] Coordinate Transform
  [PASS] Time Utilities
  [PASS] Inpaint NaNs
  [PASS] LiDAR Bathymetry

  8/8 tests passed
============================================================

Package Structure

scarp/
├── config.py              # Physical constants and site parameters
├── io/                    # Input/Output
│   ├── las_reader.py      # LAS point cloud file reading
│   ├── mat_io.py          # MATLAB .mat file I/O
│   └── noaa_api.py        # NOAA tide gauge API
├── processing/            # Data Processing
│   ├── lidar/
│   │   ├── process_drone.py    # Drone LiDAR processing
│   │   ├── process_truck.py    # Truck LiDAR processing
│   │   ├── prep_timestack.py   # Timestack preparation
│   │   ├── sort_las.py         # LAS sorting utilities
│   │   └── remove_wiggles.py   # Systematic error removal
│   └── pressure/
│       ├── process_paros.py    # Paros sensor processing
│       ├── pcorrect.py         # Pressure corrections
│       └── burial_correction.py # Burial depth correction
├── analysis/              # Analysis Modules
│   ├── bathymetry/
│   │   ├── get_lidar_bathy.py  # Bathymetry from wave tracking
│   │   ├── lidar_bathy_error.py # Error estimation
│   │   ├── get_bathy_grid.py   # Gridded bathymetry
│   │   └── phase_speed_gradient.py
│   ├── runup/
│   │   ├── runup_stats.py      # Runup statistics
│   │   └── process_runup.py    # Runup processing
│   ├── waves/
│   │   ├── spectral.py         # Spectral analysis
│   │   └── dispersion.py       # Wave dispersion relations
│   └── mops/
│       ├── qc_paros.py         # Quality control
│       └── get_paros_hourly.py # Hourly data extraction
├── utils/                 # Utilities
│   ├── time_utils.py      # GPS/UTC time conversion
│   ├── coord_transform.py # UTM/lat-lon transformations
│   ├── signal_processing.py
│   └── array_utils.py
├── external/              # External Library Equivalents
│   ├── jlab_equiv.py      # jlab toolbox functions
│   └── mops_stub.py       # MOPS toolbox stub
└── plotting/              # Visualization (minimal)

Quick Start

Processing LiDAR Data

from scarp.processing.lidar import process_drone_lidar, prep_timestack
from scarp.io import load_mat

# Process drone LiDAR files
processed = process_drone_lidar(
    las_files=['hover1.las', 'hover2.las'],
    origin_utm=(476000, 3638000),
    theta=0.14,  # Shore-normal rotation angle (radians)
    dx=0.1,      # 10 cm spatial resolution
)

# Combine drone and truck data into timestack
timestack = prep_timestack(
    drone_data=drone_processed,
    truck_data=truck_processed,
    tstart=737773.5,  # MATLAB datenum
    tstop=737773.6,
)

Extracting Bathymetry from Wave Crest Tracking

from scarp.analysis.bathymetry import get_lidar_bathy
import numpy as np

# Load timestack data
data = load_mat('timestack.mat')

# De-mean elevation
Z = data['TXdrone2']
eta = Z - np.nanmean(Z, axis=0, keepdims=True)

# Extract bathymetry using wave crest tracking
result = get_lidar_bathy(
    eta=eta.T,           # Shape: (nx, nt)
    x=data['Xgrid'][:, 0],
    dt=0.1,              # 10 Hz sampling
    use_robust_regression=True,
    adaptive_window=True,
)

# Access results
depth_linear = result.h_linear    # c^2/g
depth_bore = result.h_bore        # c^2/g - H/2 (bore correction)
celerity = result.c_median
wave_height = result.H_mean

Spectral Analysis

from scarp.analysis.waves import compute_wave_stats
from scarp.external.jlab_equiv import mspec

# Compute wave statistics from time series
stats = compute_wave_stats(
    x=elevation_timeseries,
    fs=2.0,  # 2 Hz sampling
)

print(f"Significant wave height: {stats['Hs_total']:.2f} m")
print(f"Peak period: {stats['Tp']:.1f} s")

# Multitaper spectral analysis
f, S = mspec(dt=0.5, x=timeseries, nw=4)

Time Conversion

from scarp.utils.time_utils import gps_to_utc, datenum_to_datetime

# Convert GPS time to UTC
t_utc, t_local = gps_to_utc(
    gps_seconds,
    filename='scan_20191214.las'
)

# Convert MATLAB datenum to Python datetime
dt = datenum_to_datetime(737773.5)

Coordinate Transformation

from scarp.utils.coord_transform import ll2utm, utm2ll, xy_rotate

# Convert lat/lon to UTM
x_utm, y_utm, zone = ll2utm(lat, lon)

# Convert UTM back to lat/lon
lat, lon = utm2ll(x_utm, y_utm, zone=zone)

# Rotate to shore-normal coordinates
x_local, y_local = xy_rotate(x_utm, y_utm, theta, x_origin, y_origin)

Key Algorithms

Bathymetry Extraction (get_lidar_bathy)

Extracts nearshore bathymetry from LiDAR timestacks using wave crest tracking:

  1. Spectral Analysis: Compute peak frequency at each cross-shore location using multitaper methods
  2. Crest Detection: Identify wave crests at domain edge using windowed peak finding
  3. Crest Tracking: Track each crest shoreward with sliding window approach
  4. Bore Detection: Detect breaking waves/bores when wave front becomes flat
  5. Celerity Estimation: Compute wave speed using robust regression (Huber M-estimator)
  6. Depth Estimation: Apply linear theory (h = c²/g) or bore correction (h = c²/g - H/2)

Physical Methods

  • Linear wave dispersion: ω² = gk tanh(kh)
  • Shallow water approximation: c = √(gh)
  • Stockdon et al. 2006: Runup parameterization
  • Yamamoto et al. 1978: Porous media wave propagation
  • Bonneton pressure correction: Subsurface pressure to surface elevation

Data Files

The mat/ directory contains:

  • sensors.mat - Sensor deployment metadata (UTM coordinates, NAVD88 elevations)
  • MOP582.mat - 18 years of oceanographic observations from Scripps Pier

Large data files (LAS, raw pressure) are excluded from git via .gitignore.

MATLAB to Python Mapping

MATLAB Function Python Module
process_drone_lidar.m processing.lidar.process_drone
process_truckanddronelidar.m processing.lidar.process_truck
prep_timestack_clean.m processing.lidar.prep_timestack
get_lidarBathy.m analysis.bathymetry.get_lidar_bathy
get_runupStatsLidar.m analysis.runup.runup_stats
pcorrect_Bonneton.m processing.pressure.pcorrect
burialcorrection.m processing.pressure.burial_correction
GPStoUTC.m utils.time_utils.gps_to_utc
lasdata.m io.las_reader
jlab (sleptap, mspec) external.jlab_equiv

References

  • Martins, K., et al. (2017). "High frequency field measurements of an undular bore using a 2D LiDAR scanner"
  • Stockdon, H.F., et al. (2006). "Empirical parameterization of setup, swash, and runup"
  • Yamamoto, T., et al. (1978). "On the response of a poro-elastic bed to water waves"
  • Raubenheimer, B., et al. (1998). "Pressure sensor calibration"

License

[Add license information]

Contact

  • Original MATLAB Code: Julia Fiedler (jfiedler@ucsd.edu)
  • Site: Scripps Institution of Oceanography, UC San Diego

About

codes for Storm CoAstal Response Project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • MATLAB 59.8%
  • Python 40.2%