Skip to content

Commit

Permalink
New option for fetchdata: --sds to retrieve waveform data from a …
Browse files Browse the repository at this point in the history
…SDS archive
  • Loading branch information
claudiodsf committed Dec 2, 2024
1 parent 374d219 commit e59ec28
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Copyright (c) 2022-2024 Claudio Satriano <[email protected]>
## unreleased

- `seiscat download` renamed to `seiscat fetchdata`
- New option for `seiscat fetchdata`: `--sds` to retrieve waveform data from
a local SDS archive
- New option for `seiscat initdb` and `seiscat updatedb`: `--fromfile` to
initialize or update the database from a CSV file

Expand Down
15 changes: 11 additions & 4 deletions seiscat/fetchdata/event_waveforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
(https://www.gnu.org/licenses/gpl-3.0-standalone.html)
"""
import pathlib
from .sds import get_sds_client, fetch_sds_waveforms
from .mass_downloader import mass_download_waveforms
from ..database.dbfunctions import read_events_from_db
from ..utils import ExceptionExit
Expand All @@ -24,7 +25,13 @@ def fetch_event_waveforms(config):
"""
with ExceptionExit():
events = read_events_from_db(config)
event_dir = pathlib.Path(config['event_dir'])
event_dir.mkdir(parents=True, exist_ok=True)
for event in events:
mass_download_waveforms(config, event)
event_dir = pathlib.Path(config['event_dir'])
event_dir.mkdir(parents=True, exist_ok=True)
args = config['args']
if args.sds:
sds_client = get_sds_client(args.sds)
for event in events:
fetch_sds_waveforms(config, event, sds_client)
else:
for event in events:
mass_download_waveforms(config, event)
86 changes: 86 additions & 0 deletions seiscat/fetchdata/sds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -*- coding: utf8 -*-
# SPDX-License-Identifier: GPL-3.0-or-later
"""
Fetch event waveforms from a local SDS archive.
:copyright:
2022-2024 Claudio Satriano <[email protected]>
:license:
GNU General Public License v3.0 or later
(https://www.gnu.org/licenses/gpl-3.0-standalone.html)
"""
import pathlib
import re
from obspy.clients.filesystem.sds import Client


def get_sds_client(sds_root):
"""
Get an SDS client.
:param sds_root: path to SDS archive
:type sds_root: str
:return: SDS client
:rtype: obspy.clients.filesystem.sds.Client
"""
client = Client(sds_root)
all_nslc = client.get_all_nslc()
if not all_nslc:
raise FileNotFoundError(
f'No SDS archive found in {sds_root}')
return client


def _check_channel(channel, channel_priorities):
"""
Check if a channel is in the list of channel priorities.
:param channel: channel code
:type channel: str
:param channel_priorities: list of channel codes
:type channel_priorities: list
:return: True if the channel is in the list of channel priorities
:rtype: bool
"""
for priority in channel_priorities:
# Convert wildcard pattern to regex pattern
regex_pattern = re.escape(priority)\
.replace(r'\*', '.*').replace(r'\?', '.')
# Handle character sets like [ZNE]
regex_pattern = re.sub(r'\\\[([^\\\]]+)\\\]', r'[\1]', regex_pattern)
if re.fullmatch(regex_pattern, channel):
return True
return False


def fetch_sds_waveforms(config, event, client):
"""
Fetch event waveforms from a local SDS archive.
:param config: config object
:type config: dict
:param event: an event dictionary
:type event: dict
:param client: SDS client
:type client: obspy.clients.filesystem.sds.Client
"""
event_dir = pathlib.Path(config['event_dir'], event['evid'], 'waveforms')
event_dir.mkdir(parents=True, exist_ok=True)
seconds_before = config['seconds_before_origin']
seconds_after = config['seconds_after_origin']
t0 = event['time'] - seconds_before
t1 = event['time'] + seconds_after
channel_priorities = config['channel_priorities']
print(f'Fetching waveforms for event: {event["evid"]}')
all_nslc = client.get_all_nslc()
for nslc in all_nslc:
if not _check_channel(nslc[-1], channel_priorities):
continue
net, sta, loc, chan = nslc
st = client.get_waveforms(net, sta, loc, chan, t0, t1)
outfile = event_dir / f'{net}.{sta}.{loc}.{chan}.mseed'
st.write(outfile, format='MSEED')
print(f' {outfile} written')
print()
6 changes: 6 additions & 0 deletions seiscat/parse_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ def parse_arguments():
help='fetch full event details and/or waveform data and metadata',
formatter_class=NewlineHelpFormatter
)
fetchdata_parser.add_argument(
'-s', '--sds',
metavar='SDS_DIR',
type=str,
help='fetch waveform data from a local SDS archive'
)
fetchdata_parser.add_argument(
'eventid', nargs='?',
help='event ID to download (default: all events)'
Expand Down

0 comments on commit e59ec28

Please sign in to comment.