地震波形数据下载:从IRIS到SAC的踩坑记录
上周帮同事处理一批2019年加州Ridgecrest地震序列的波形,环境是Ubuntu 22.04,Python 3.10,ObsPy 1.4.0。数据量不大,约200个事件,每个事件下载3个台站的三分量,总共不到2GB。但整个过程踩了两个坑,记下来给需要的人。
第一个坑是下载超时。直接用obspy.clients.fdsn的Client下载,默认超时30秒,但在批量请求时偶尔会卡住。我的做法是给每次请求加超时和重试:
from obspy.clients.fdsn import Client
from obspy import UTCDateTime
import time
client = Client("IRIS", timeout=120)
for event in events:
for attempt in range(3):
try:
st = client.get_waveforms("*", "*", "*", "BH?",
event.time - 60,
event.time + 600,
attach_response=True)
break
except Exception as e:
print(f"retry {attempt}: {e}")
time.sleep(5)
else:
print(f"failed: {event.resource_id}")
continue
st.write(f"{event.resource_id}.mseed", format="MSEED")
这里用attach_response=True是为了后面去仪器响应,但注意IRIS返回的StationXML可能较大,批量下会占内存,所以我分事件写盘,不一次性全放内存。
第二个坑是台站通道匹配。一开始用channel="BH?"想抓宽频带,但有些台站只有HH?或EH?,结果漏了。后来改成channel="*"再按采样率筛选,但这样会下载很多短周期数据,浪费流量。折中方案是先查台站元数据:
inv = client.get_stations(network="*", station="*", level="channel",
starttime=t1, endtime=t2,
channel="BH?,HH?,EH?")
然后从inv里挑出有BH?或HH?的台站,再用具体台站代码下载。代价是多一次请求,但能避免重下。
为什么用SAC格式?因为后续要用SAC的rmean和rtrend做预处理,但其实ObsPy也能做,只是同事习惯SAC。转格式时用st.write(..., format="SAC"),注意SAC对时间精度只到毫秒,且台站名超过8字符会截断(IRIS现在有长台站名,比如CI.CLC没问题,但有些台站如CI.USB也OK,遇到NN.xxxx可能出问题)。我就碰到一个台站名CI.PASC正常,但CI.LJR也正常,没截断,但文档说SAC头段限8字符,所以保险起见我检查了st[0].stats.station长度。
失效的地方:如果事件时间范围跨年,IRIS的get_waveforms可能返回空,因为数据分块存储;我遇到2019年12月的事件下载正常,但2020年1月的就失败了,后来改成按天分段请求才解决。另外,attach_response=True在批量下载时偶尔会因StationXML解析报错,我干脆先下载波形不带响应,再单独下载响应文件,用st.attach_response(inv)挂上去。
最后留个问题:你们在批量下载波形时,是直接按事件循环请求,还是先列出台站列表再按台站循环?我按事件循环感觉请求数多,但按台站循环又得处理时间窗,有点纠结,想听听别人的做法。
0 条评论
还没有评论,写下第一条。