Session 5: OOI Regional Cabled Array DAS- Event Denoising and Detection#

Author: Qibin Shi (qs20@rice.edu; qibin.nan@gmail.com)

Last updated: Dec 7, 2025

This notebook provides a demo on processing the data from the Ocean Observatories Initiative (OOI)

Regional Cabled Array’s Distributed Acoustic Sensing (DAS) to detect regional earthquakes.

Overview#

The data for this experiment was acquired using the OptoDAS system from Alcatel Subsea Networks.

The focus was on the South Cable of the OOI RCA.

Data Access (not for this tutorial)#

The complete OptoDAS data can be accessed via the following link:

OptoDAS Data Repository

The data is organized into directories named by date. Here’s a breakdown:

  • 200G: 2024-05-06

  • 617G: 2024-05-07

  • 617G: 2024-05-08

  • 617G: 2024-05-09

  • 382G: 2024-05-10

For details on how to read and manipulate the HDF5 format data, refer to the

example code in this repository.

Cable Geometry#

The map shows the OOI RCA cables (black lines) and the interrogated segment (red line)

between the Oregon coast and the repeater (red dots). Bathymetric contours are in meters.

The inset map indicates full-length cables, seafloor nodes, coastal lines, and plate boundaries.

import warnings
warnings.filterwarnings('ignore')
import os
import gc

import sys
sys.path.append('./utils_for_denodas/')

import h5py
import numpy as np

import torch
import torch.nn as nn
import seisbench.models as sbm

from das_util import *
from denodas_model import unet
from scipy.signal import filtfilt, butter, decimate
from scipy.interpolate import interp1d

import obspy
from obspy import UTCDateTime
from obspy.clients.fdsn import Client

import matplotlib
from matplotlib import pyplot as plt
matplotlib.rcParams['font.family'] = 'sans-serif'
matplotlib.rcParams['font.sans-serif'] = ['DejaVu Sans']
matplotlib.rcParams['font.size'] = 22

import psutil, os
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")

### Directory for data and denoising model
rawdata_dir = '/1-fnp/petasaur/p-wd02/muxDAS/'
rawdata_dir = '../../data/qibin/'
model_dir = './utils_for_denodas/denoiser_weights_LR08_MASK05_raw2raw_old.pt'
data_picked =  False
RSS GB: 0.52

Metadata of 2024 OOI DAS#

Select a file to extract metadata

# fname = os.path.join(rawdata_dir, '20240510/dphi/024905.hdf5')
fname = os.path.join(rawdata_dir, '024905.hdf5')

gl, t0, dt, fs, dx, un, ns, nx = extract_metadata(fname, machine_name='optodas')

t0 = UTCDateTime(t0)

print('Start time:\t\t\t', t0)
print('Unit:\t\t\t\t',un.decode('UTF-8'))
print('Gauge length (m):\t\t', gl)
print('Sampling rate (Hz):\t\t',fs)
print('Sample interval (s):\t\t',dt)
print('Channel interval (m):\t\t',dx)
print('Number of samples:\t\t',ns)
print('Number of channels:\t\t',nx)
Start time:			 2024-05-10T02:49:05.302000Z
Unit:				 rad/(s*m)
Gauge length (m):		 40.85200763098726
Sampling rate (Hz):		 200.0
Sample interval (s):		 0.005
Channel interval (m):		 10.213001907746815
Number of samples:		 2000
Number of channels:		 9500

Visualize the cable coordinate

### Get the cable latitude, longitude, and depth
cable = np.genfromtxt('./utils_for_denodas/south_DAS_latlondepth.txt')
lat = cable[:,1]
lon = cable[:,2]
dep = cable[:,3]

### Plot cable geometry
plt.figure(figsize=(15, 1.5))
cb = plt.scatter(lon, lat, c=dep, marker='.', cmap='jet')
plt.colorbar(cb, label='elevation (m)', aspect=20)
plt.gca().set_aspect('equal')
plt.title('Cable geometry')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
Text(0, 0.5, 'Latitude')
../../_images/3a47183509d2fa0b48a29b7bd30a19907ae45ea8b6d247b8b20b850afbb12491.png

DAS data processing#

Select a starting time that match the saved data.

imin = '0249'

# imin = '1338'
# imin = '0956'

Read one-minute data

### A list of suffixes presenting starting seconds
### of each 10-second file
files = ['05', '15', '25', '35', '45', '55']

### Read this six files and concatenate to form one 60-second data
### 9000 channels starting from ch 500 (5km) to avoid onshore cable part
### 2000 samples for each 10-second file at 200 Hz sampling rate
minute_data = np.zeros((9000, 12000), dtype=np.float32)
st_pt = 0

for k in range(len(files)): 

    fname = os.path.join(rawdata_dir, imin+files[k]+'.hdf5')
    with h5py.File(fname, 'r') as f:

        time_data =f['data'][:2000, 500:9500]

    minute_data[:time_data.shape[1], st_pt:st_pt+time_data.shape[0]] = time_data.T

    st_pt += time_data.shape[0]

    ### delete time_data to free memory
    del time_data
    gc.collect()

d_st = dx * 500 /1000 - 1.860  # distance shift due to starting from ch 500
### print the shape of the concatenated data
print('Data shape (channels, time points):', minute_data.shape)
print('Distance shift (km):\t\t', d_st)
Data shape (channels, time points): (9000, 12000)
Distance shift (km):		 3.246500953873407

Downsample channels by 6 and time points by 8.

Reduced resolution is 61 m x 0.04 s, sufficient for regional earthquakes

### Decimate data to reduce computational cost
tmp = decimate(minute_data,8)
tmp = decimate(tmp,6, axis=0)

### time and distance intervals after decimation
dt_new = dt * 8
dx_new = dx * 6
nx = tmp.shape[0]
nt = tmp.shape[1]

### time and distance axes after decimation
t_ax = np.arange(nt)*dt_new + int(files[0])
d_ax = np.arange(nx)*dx_new/1000 + d_st

### print updated metadata
print('\nAfter decimation:')
print('New sample interval (s):\t',dt_new)
print('New channel interval (m):\t',dx_new)
print('New number of channels:\t\t',nx)
print('New number of samples:\t\t',nt)

### delete large variables to free memory
del minute_data
gc.collect()
After decimation:
New sample interval (s):	 0.04
New channel interval (m):	 61.27801144648089
New number of channels:		 1500
New number of samples:		 1500
0

Bandpass filter to 1-6 Hz

This removes ocean waves < 1 Hz and instrument noise > 6 Hz

b, a = butter(4, (1, 6), fs=25, btype='bandpass')
filt = filtfilt(b, a, tmp, axis=1)
filtered_data = filt - np.mean(filt, axis=(0,1), keepdims=True)


### check memory usage
del filt
gc.collect()
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 0.63

Visualize the raw and filtered data

### Figure size and height partition
fig, ax = plt.subplots(3, 1, figsize=(20, 12), tight_layout=True, 
                       gridspec_kw={'height_ratios': [3, 3, 1]})

### Plot the raw data
im = ax[0].pcolor(d_ax, t_ax, tmp.T, cmap='RdBu',
                  vmin=-np.std(tmp), vmax=np.std(tmp),
                  shading='auto', rasterized=True)
fig.colorbar(im, ax=ax[0], aspect=40, label='Normalized strain rate (1 / s)')
ax[0].set_ylabel('Time (s)')
ax[0].invert_xaxis()
ax[0].invert_yaxis()
ax[0].set_title('Raw data')

### Plot the filtered data
im = ax[1].pcolor(d_ax, t_ax, filtered_data.T, cmap='RdBu',
                  vmin=-np.std(filtered_data), vmax=np.std(filtered_data),
                  shading='auto', rasterized=True)
fig.colorbar(im, ax=ax[1], aspect=40, label='Normalized strain rate (1 / s)')
ax[1].set_xlabel('Distance from shore (km)')
ax[1].set_ylabel('Time (s)')
ax[1].invert_xaxis()
ax[1].invert_yaxis()
ax[1].set_title('Filtered data (1-6 Hz)')

### Plot cable geometry
cb = ax[2].scatter(lon, lat, c=dep, marker='.', cmap='jet')
fig.colorbar(cb, ax=ax[2], label='elevation (m)', aspect=20)
ax[2].set_aspect('equal')
ax[2].set_title('Cable geometry')
ax[2].set_xlabel('Longitude')
ax[2].set_ylabel('Latitude')
Text(0, 0.5, 'Latitude')
../../_images/8332822254b7f78963455fcb73476295e2e2582881764dc44c4dbd10784806ca.png
fig.clf()
plt.close()
del fig, ax, im, cb
gc.collect()

### check memory usage
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 1.05

DAS denoising#

Prepare the denoising model

### Initialize the U-net
devc = torch.device('cpu')
model_1 = unet(1, 16, 1024, factors=(5, 3, 2, 2), use_att=False)
model_1.to(devc)

### Convert multi-GPU trained model to single-CPU model
state_dict = torch.load(model_dir, map_location=torch.device('cpu'))
new_state_dict = {}
for k, v in state_dict.items():
    new_k = k.replace("module.", "")   # remove prefix
    new_state_dict[new_k] = v

### Load the pretrained weights
model_1.load_state_dict(new_state_dict)
model_1.eval() 
unet(
  (relu): ReLU()
  (layer): ModuleList(
    (0): Conv2d(1, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (2): MaxBlurPool2d()
    (3): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (4): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (5): MaxBlurPool2d()
    (6): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): MaxBlurPool2d()
    (9): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (10): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): Dropout(p=0.2, inplace=False)
    (12): MaxBlurPool2d()
    (13): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): Dropout(p=0.2, inplace=False)
    (16): Upsample(scale_factor=(2.0, 2.0), mode='nearest')
    (17-18): 2 x Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (19): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): Upsample(scale_factor=(2.0, 2.0), mode='nearest')
    (21-22): 2 x Conv2d(128, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (23): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (24): Upsample(scale_factor=(3.0, 3.0), mode='nearest')
    (25-26): 2 x Conv2d(64, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (27): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (28): Upsample(scale_factor=(5.0, 5.0), mode='nearest')
    (29-30): 2 x Conv2d(32, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (31): Conv2d(16, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (32): Conv2d(16, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  )
)

Apply denoising model

### Denoising
one_denoised, mul_denoised = Denoise_largeDAS(filtered_data/np.std(filtered_data, axis=(0,1), keepdims=True), 
                                                model_1, devc, repeat=4, norm_batch=False)

### Normalize the denoised data
mul_denoised = (mul_denoised-np.mean(mul_denoised, axis=(0,1), keepdims=True)) * np.std(mul_denoised, axis=(0,1), keepdims=True)

### Bandpass filter
b, a = butter(4, (1, 6), fs=25, btype='bandpass')
filt = filtfilt(b, a, mul_denoised, axis=1)
mul_denoised = filt - np.mean(filt, axis=(0,1), keepdims=True)

### check memory usage
del filt, one_denoised
gc.collect()
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
torch.Size([1, 1500, 1500])
RSS GB: 1.18

Phase picking#

Use ELEP (Yuan et al., 2024) to pick seismo-acoustic phases

Load the picker

### ML picker parameters
paras_semblance = {'dt':0.01, 
                   'semblance_order':2, 
                   'window_flag':True, 
                   'semblance_win':0.5, 
                   'weight_flag':'max'}

### Download models
devcc = torch.device('cpu')

pn_ethz_model = sbm.EQTransformer.from_pretrained("ethz")
pn_instance_model = sbm.EQTransformer.from_pretrained("instance")
pn_scedc_model = sbm.EQTransformer.from_pretrained("scedc")
pn_stead_model = sbm.EQTransformer.from_pretrained("stead")
pn_geofon_model = sbm.EQTransformer.from_pretrained("geofon")
pn_neic_model = sbm.EQTransformer.from_pretrained("neic")

pn_ethz_model.to(devcc)
pn_scedc_model.to(devcc)
pn_neic_model.to(devcc)
pn_geofon_model.to(devcc)
pn_stead_model.to(devcc)
pn_instance_model.to(devcc)

list_models = [pn_ethz_model,pn_scedc_model,pn_neic_model,
               pn_geofon_model,pn_stead_model,pn_instance_model]

Interpolate along the time axis for picking

### The phase picker needs 6000 time points as input
interp_func = interp1d(np.linspace(0, 1, 1500), 
                       filtered_data/np.std(filtered_data), 
                       axis=-1, kind='linear')
interpolated_image = interp_func(np.linspace(0, 1, 6000))

interp_func = interp1d(np.linspace(0, 1, 1500), 
                       mul_denoised/np.std(mul_denoised), 
                       axis=-1, kind='linear')
interpolated_muldenoised = interp_func(np.linspace(0, 1, 6000))

Apply picker on interpolated data

### Pick RAW data, every 2 channels
print('Start picking raw data ...')
image1 = np.nan_to_num(interpolated_image[::2,:])
raw_picks = apply_elep(image1, list_models, 100, paras_semblance, devcc)
print('Finished picking raw data.')

### Pick mulDENOISED, every 2 channels
print('Start picking denoised data ...')
image2 = np.nan_to_num(interpolated_muldenoised[::2,:])
mul_picks = apply_elep(image2, list_models, 100, paras_semblance, devcc)
print('Finished picking denoised data.')

data_picked =  True

### check memory usage
del interpolated_image, interpolated_muldenoised, image1, image2, \
pn_ethz_model, pn_scedc_model, pn_neic_model, \
pn_geofon_model, pn_stead_model, pn_instance_model, model_1
gc.collect()
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 1.18

Compare raw and denoised earthquake signals and phase picks#

First, set space and time range to zoom in the signal

### Specify the distance range and time range for plotting
d1_trimed = 30 # km
d2_trimed = 95 # km

t1_trimed = 12 # s
t2_trimed = 32 # s

d1_trimed_idx = int((d1_trimed - d_st) * 1000 / dx_new)
d2_trimed_idx = int((d2_trimed - d_st) * 1000 / dx_new)
t1_trimed_idx = int((t1_trimed - int(files[0])) / dt_new)
t2_trimed_idx = int((t2_trimed - int(files[0])) / dt_new)

### Trim data for visualization
rawdata = filtered_data[d1_trimed_idx:d2_trimed_idx, t1_trimed_idx:t2_trimed_idx]
denoised = mul_denoised[d1_trimed_idx:d2_trimed_idx, t1_trimed_idx:t2_trimed_idx]

### update nx, nt, t_ax, d_ax
nx_trimed = rawdata.shape[0]
nt_trimed = rawdata.shape[1]

t_ax_trimed = t_ax[t1_trimed_idx:t2_trimed_idx]
d_ax_trimed = d_ax[d1_trimed_idx:d2_trimed_idx]

### Normalize trimmed data along time axis
rawdata = (rawdata - np.mean(rawdata, axis=1, keepdims=True))/np.std(rawdata, axis=1, keepdims=True)
denoised = (denoised - np.mean(denoised, axis=1, keepdims=True))/np.std(denoised, axis=1, keepdims=True)

if data_picked:
    raw_picks_trimed = raw_picks[d1_trimed_idx//2:d2_trimed_idx//2, :, :]
    mul_picks_trimed = mul_picks[d1_trimed_idx//2:d2_trimed_idx//2, :, :]

### check memory usage
del raw_picks, mul_picks, filtered_data, mul_denoised
gc.collect()
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 1.18

Plot the trimmed DAS data

### Figure size
fig, ax = plt.subplots(2, 1, figsize=(20, 10), tight_layout=True)

### Plot the raw data
im = ax[0].pcolor(d_ax_trimed, t_ax_trimed, rawdata.T, cmap='RdBu',
                  vmin=-np.std(rawdata)*4, vmax=np.std(rawdata)*4,
                  shading='auto', rasterized=True)
fig.colorbar(im, ax=ax[0], aspect=40, label='Normalized strain rate (1 / s)')

ax[0].set_ylabel('Time (s)')
ax[0].invert_xaxis()
ax[0].invert_yaxis()
ax[0].set_title('Before denoising')

### Plot the denoised data
im = ax[1].pcolor(d_ax_trimed, t_ax_trimed, denoised.T, cmap='RdBu',
                  vmin=-np.std(denoised)*4, vmax=np.std(denoised)*4,
                  shading='auto', rasterized=True)
fig.colorbar(im, ax=ax[1], aspect=40, label='Normalized strain rate (1 / s)')

ax[1].set_xlabel('Distance from shore (km)')
ax[1].set_ylabel('Time (s)')
ax[1].invert_xaxis()
ax[1].invert_yaxis()
ax[1].set_title('After denoising')

### Overlay picks
if data_picked:
    ind_good = np.where(raw_picks_trimed[:,1,1]>0.07)[0]
    print("number of good picks on raw data: ",len(ind_good))
    ax[0].scatter(d_ax_trimed[ind_good*2], raw_picks_trimed[ind_good,1,0]+5,c='g', marker='x', alpha=0.5)

    ind_good = np.where(mul_picks_trimed[:,1,1]>0.07)[0]
    print("number of good picks after denoising: ",len(ind_good))
    ax[1].scatter(d_ax_trimed[ind_good*2], mul_picks_trimed[ind_good,1,0]+5, c='g', marker='x', alpha=0.5)
number of good picks on raw data:  25
number of good picks after denoising:  141
../../_images/4812e084af02844e28472397aa5cd3fe1b8ca1362331bc785aeeac2ff2dbdf96.png
## clear all variables to free memory
del rawdata, denoised, raw_picks_trimed, mul_picks_trimed
gc.collect()

fig.clf()
plt.close()
del fig, ax, im
gc.collect()

### check memory usage
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 1.18

Check OBS for this event#

First, get a list of regional OBS

client = Client("IRIS")
t1 = UTCDateTime("2024-05-06")
t2 = UTCDateTime("2024-05-10")

inventory = client.get_stations(network="OO", channel="?H?",
                                starttime=t1, endtime=t2, 
                                maxlatitude=46.947, minlatitude=43.437, 
                                maxlongitude=-123.6621, minlongitude=-129.6803)

inventory
Inventory created at 2025-12-10T01:47:20.318900Z
	Created by: IRIS WEB SERVICE: fdsnws-station | version: 1.1.52
		    http://service.iris.edu/fdsnws/station/1/query?starttime=2024-05-06...
	Sending institution: IRIS-DMC (IRIS-DMC)
	Contains:
		Networks (1):
			OO
		Stations (5):
			OO.HYS11 (RSN Hydrate Summit 1-1)
			OO.HYS12 (RSN Hydrate Summit 1-2)
			OO.HYS13 (RSN Hydrate Summit 1-3)
			OO.HYS14 (RSN Hydrate Summit 1-4)
			OO.HYSB1 (RSN Hydrate Slope Base)
		Channels (0):

Specify starting time to download seismic network data

t1 = UTCDateTime("2024-05-10T02:48:10")
# t1 = UTCDateTime("2024-05-08T13:37:00")

Loop over all stations to visualize waveforms

for net in inventory:
    network = net.code

    for sta in net:
        station = sta.code
        latitude = sta.latitude
        longitude = sta.longitude
        elevation = sta.elevation
        
        ### Download waveform data
        print(f"--- Downloading data for {network}.{station} on {t1} ---")
        try:
            sdata = Client("IRIS").get_waveforms(network=network, 
                                            station=station,
                                            location="*", 
                                            channel="BH?,EH?", 
                                            starttime=t1+0,
                                            endtime=t1 + 290)
            
        except obspy.clients.fdsn.header.FDSNNoDataException:
            print(f"--- No data for {network}.{station} on {t1} ---")
            continue

        ### Check sampling rates and resample if needed
        fs_all = [tr.stats.sampling_rate for tr in sdata]
        fs = np.round(fs_all[0])
        if fs > 100:
            sdata = sdata.resample(100)
            print(f"--- Resampled {100} Hz for {network}.{station} on {t1} ---")
        elif len(np.unique(np.array(fs_all))) > 1:      
            print(f"--- Sampling rates are different for {network}.{station} on {t1} ---")
            sdata = sdata.resample(fs)
            print(f"--- Resampled {fs} Hz for {network}.{station} on {t1} ---")

        ### Merge, filter, and align data
        print(f"--- Merging data for {network}.{station} on {t1} ---")
        sdata.merge(fill_value='interpolate')  # fill gaps
        sdata.filter("bandpass", freqmin=3, freqmax=20, corners=4, zerophase=True) 
        btime = sdata[0].stats.starttime

        print(f"--- Aligning data for {network}.{station} on {t1} ---")
        # align 3 components
        max_b = max([tr.stats.starttime for tr in sdata])
        min_e = min([tr.stats.endtime for tr in sdata])
        for tr in sdata:
            tr.trim(starttime=max_b+10, endtime=min_e, nearest_sample=True)  

        ### Plot waveforms 
        fig, ax = plt.subplots(len(sdata), 1, figsize=(15, 6), sharex=True)
        for i, tr in enumerate(sdata):
            ax[i].plot(tr.times("relative"), tr.data, "k")
            ax[i].set_ylabel(f"{tr.stats.channel}")
   
        ax[-1].set_xlabel("Time (s)")
        ax[0].set_title(f"{network}.{station} on {t1}")
    
        plt.tight_layout()
        plt.show()

        del sdata
        gc.collect()

        fig.clf()
        plt.close()
        del fig, ax
        gc.collect()

        ### check memory usage
        proc = psutil.Process(os.getpid())
        print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
--- Downloading data for OO.HYS11 on 2024-05-10T02:48:10.000000Z ---
--- Resampled 100 Hz for OO.HYS11 on 2024-05-10T02:48:10.000000Z ---
--- Merging data for OO.HYS11 on 2024-05-10T02:48:10.000000Z ---
--- Aligning data for OO.HYS11 on 2024-05-10T02:48:10.000000Z ---
../../_images/4fb24e9349b411cede938b7da2cd64ec83578e11345e9e51f5a57217e0c8af3e.png
RSS GB: 1.19
--- Downloading data for OO.HYS12 on 2024-05-10T02:48:10.000000Z ---
--- Resampled 100 Hz for OO.HYS12 on 2024-05-10T02:48:10.000000Z ---
--- Merging data for OO.HYS12 on 2024-05-10T02:48:10.000000Z ---
--- Aligning data for OO.HYS12 on 2024-05-10T02:48:10.000000Z ---
../../_images/8d78fbd301efbafe6c7dd23b2d21e3c96566f9ed1a22c906d6c9dad46df1290a.png
RSS GB: 1.19
--- Downloading data for OO.HYS13 on 2024-05-10T02:48:10.000000Z ---
--- Resampled 100 Hz for OO.HYS13 on 2024-05-10T02:48:10.000000Z ---
--- Merging data for OO.HYS13 on 2024-05-10T02:48:10.000000Z ---
--- Aligning data for OO.HYS13 on 2024-05-10T02:48:10.000000Z ---
../../_images/0e9f4e478e0c1fbb5c152053d55ced633a23bd7afbfe435284c2b2db41897f2d.png
RSS GB: 1.19
--- Downloading data for OO.HYS14 on 2024-05-10T02:48:10.000000Z ---
--- Merging data for OO.HYS14 on 2024-05-10T02:48:10.000000Z ---
--- Aligning data for OO.HYS14 on 2024-05-10T02:48:10.000000Z ---
../../_images/3873f494850e0b155bd4c5bd24fd9d1ae56028583c31a2eefc1a3520eaa36cdf.png
RSS GB: 1.19
--- Downloading data for OO.HYSB1 on 2024-05-10T02:48:10.000000Z ---
--- No data for OO.HYSB1 on 2024-05-10T02:48:10.000000Z ---
### check memory usage
proc = psutil.Process(os.getpid())
print(f"RSS GB: {proc.memory_info().rss/1e9:.2f}")
RSS GB: 1.19

What next?#

Reference#

  • Self-supervised machine learing for DAS: Denolle-Lab/Shi_etal_2023_denoiseDAS

  • Shi, Q., Williams, E. F., Lipovsky, B. P., Denolle, M. A., Wilcock, W. S., Kelley, D. S., & Schoedl, K. (2025). Multiplexed distributed acoustic sensing offshore central Oregon. Seismological Research Letters, 96(2A), 784-800.

  • Shi, Q., Denolle, M. A., Ni, Y., Williams, E. F., & You, N. (2025). Denoising offshore distributed acoustic sensing using masked auto‐encoders to enhance earthquake detection. Journal of Geophysical Research: Solid Earth, 130(2), e2024JB029728.