This will compuete PSD for continuous seismic waveforms and requires ObsPy and Matplotlib
from obspy import read, read_inventory
from obspy import UTCDateTime
from obspy.clients.fdsn import Client
from obspy.signal import PPSD
from obspy.imaging.cm import pqlx
import obspy as ob
print("# obspy version = ",ob.__version__)
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = 8,8
# font size
SMALL_SIZE = 12
MEDIUM_SIZE = 14
BIGGER_SIZE = 16
plt.rc('font', size=SMALL_SIZE) # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
This example uses NCEDC. We can use other dataceneter (e.g., SCEDC, IRIS, GEOFON...)
#client = Client("NCEDC") # data from NCEDC
#client = Client("SCEDC") # data from SCEDC
client = Client("IRIS") # data from IRIS for Cascadia SA-ULN
Which SNCL (Station, Network, Component, Location)? This example uses NSMTC.NV.CNZ.B2 data
#http://ds.iris.edu/mda/NV/NSMTC/
sta = "NSMTC" # station
net = "NV" # network
com = "CNZ" # component
loc = "B2" # location
This example uses data collected between 2018/08/15/-2018/08/16
start_day = "2018-08-15:00:00:00"
end_day = "2018-08-16:00:00:00"
starttime = UTCDateTime(start_day)
endtime = UTCDateTime(end_day)
This example uses 3600-sec-long (1hour) data
#ppsd_length = 7200 # 2h
ppsd_length = 3600 # 1h
use get_stations with level = "response"
inv = client.get_stations(network=net, station=sta, location=loc, channel=com,
starttime=starttime, endtime=endtime, level="response")
print(inv)
use get_waveforms
st = client.get_waveforms(net, sta, loc, com,
starttime, endtime)
print(st)
check waveforms
_plot = st.plot() # check waveform
use PPSD function from obsPy
# psd estimate
min_db = -200 # min. db
max_db = -50 # max db
ddb = 1 # 1 db increment
tr = st[0] # first segment only. if data have gaps, only first segment is stored
ppsd = PPSD(stats=tr.stats, metadata=inv, db_bins=(min_db, max_db, ddb), ppsd_length=ppsd_length)
# computing PSD
ppsd.add(tr)
period_low = 1/250 # 250 Hz
period_max = 1000 # 1000 sec
# probability density function of PSD plot
ppsd.plot(cmap=pqlx, period_lim=(period_low, period_max), show_mean = True, )
# spectrogram
ppsd.plot_spectrogram()