{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# WaveBank\n", "`WaveBank` is an in-process database for accessing seismic time-series data. Any directory structure containing ObsPy-readable waveforms can be used as the data source. `WaveBank` uses a simple indexing scheme and the [Hierarchical Data Format](https://en.wikipedia.org/wiki/Hierarchical_Data_Format) to keep track of each `Trace` in the directory. Without `WaveBank` (or another similar program) applications have implement their own data organization/access logic which is tedious and clutters up application code. `WaveBank` provides a better way. \n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load Example Data\n", "This tutorial will demonstrate the use of `WaveBank` on two different [obsplus datasets](../datasets/datasets.ipynb). \n", "\n", "The first dataset, [crandall canyon](https://en.wikipedia.org/wiki/Crandall_Canyon_Mine), only has event waveform files. The second only has continuous data from two TA stations. We start by loading these datasets, making a temporary copy, and getting a path to their waveform directories." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:38.144976Z", "iopub.status.busy": "2026-03-03T08:34:38.144805Z", "iopub.status.idle": "2026-03-03T08:34:39.404570Z", "shell.execute_reply": "2026-03-03T08:34:39.403706Z" } }, "outputs": [], "source": [ "%%capture\n", "import obsplus\n", "\n", "# make sure datasets are downloaded and copy them to temporary\n", "# directories to make sure no accidental changes are made\n", "crandall_dataset = obsplus.load_dataset(\"crandall_test\").copy_to()\n", "ta_dataset = obsplus.load_dataset(\"ta_test\").copy_to()\n", "\n", "# get path to waveform directories\n", "crandall_path = crandall_dataset.waveform_path\n", "ta_path = ta_dataset.waveform_path" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.406767Z", "iopub.status.busy": "2026-03-03T08:34:39.406358Z", "iopub.status.idle": "2026-03-03T08:34:39.411913Z", "shell.execute_reply": "2026-03-03T08:34:39.410994Z" } }, "outputs": [ { "data": { "text/plain": [ "PosixPath('/tmp/tmp0g7en121/crandall_test/waveforms')" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "crandall_path" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a WaveBank object\n", "To create a `WaveBank` instance simply pass the class a path to the waveform directory." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.441616Z", "iopub.status.busy": "2026-03-03T08:34:39.441254Z", "iopub.status.idle": "2026-03-03T08:34:39.457411Z", "shell.execute_reply": "2026-03-03T08:34:39.456659Z" } }, "outputs": [], "source": [ "bank = obsplus.WaveBank(crandall_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Utilizing the `udpate_index` method on the bank ensures the index is up-to-date. This will iterate through all files that are timestamped later than the last time `update_index` was run.\n", "\n", "Note: If the index has not yet been created or new files have been added, `update_index` needs to be called." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.459041Z", "iopub.status.busy": "2026-03-03T08:34:39.458877Z", "iopub.status.idle": "2026-03-03T08:34:39.595351Z", "shell.execute_reply": "2026-03-03T08:34:39.594567Z" } }, "outputs": [ { "data": { "text/plain": [ "WaveBank(base_path=/tmp/tmp0g7en121/crandall_test/waveforms, index_path=/tmp/tmp0g7en121/crandall_test/waveforms/.index.h5)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bank.update_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using a custom index path\n", "\n", "If you are working from a data directory that doesn't have write access, you can specify a custom location for the index path:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.597315Z", "iopub.status.busy": "2026-03-03T08:34:39.597137Z", "iopub.status.idle": "2026-03-03T08:34:39.689411Z", "shell.execute_reply": "2026-03-03T08:34:39.688516Z" } }, "outputs": [ { "data": { "text/plain": [ "WaveBank(base_path=/tmp/tmp0g7en121/crandall_test/waveforms, index_path=/tmp/tmp19f_bysm/index.h5)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import tempfile\n", "from pathlib import Path\n", "\n", "index_path = Path(tempfile.mkdtemp()) / \"index.h5\"\n", "cust_ind_bank = obsplus.WaveBank(crandall_path, index_path=index_path)\n", "cust_ind_bank.update_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Get waveforms\n", "\n", "The files can be retrieved from the directory with the `get_waveforms` method. This method has the same signature as the ObsPy client `get_waveform` methods so they can be used interchangeably:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.691142Z", "iopub.status.busy": "2026-03-03T08:34:39.690961Z", "iopub.status.idle": "2026-03-03T08:34:39.756453Z", "shell.execute_reply": "2026-03-03T08:34:39.755671Z" } }, "outputs": [], "source": [ "import obspy\n", "\n", "t1 = obspy.UTCDateTime(\"2007-08-06T01-44-48\")\n", "t2 = t1 + 60\n", "st = bank.get_waveforms(starttime=t1, endtime=t2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`WaveBank` can filter on channels, locations, stations, networks, etc. using linux style search strings or regex. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.758654Z", "iopub.status.busy": "2026-03-03T08:34:39.758487Z", "iopub.status.idle": "2026-03-03T08:34:39.772255Z", "shell.execute_reply": "2026-03-03T08:34:39.771435Z" } }, "outputs": [], "source": [ "st2 = bank.get_waveforms(network=\"UU\", starttime=t1, endtime=t2)\n", "\n", "# ensure only UU traces were returned\n", "for tr in st2:\n", " assert tr.stats.network == \"UU\"\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.773798Z", "iopub.status.busy": "2026-03-03T08:34:39.773630Z", "iopub.status.idle": "2026-03-03T08:34:39.783926Z", "shell.execute_reply": "2026-03-03T08:34:39.783198Z" } }, "outputs": [], "source": [ "st = bank.get_waveforms(starttime=t1, endtime=t2, station=\"O1??\", channel=\"BH[NE]\")\n", "\n", "# test returned traces\n", "for tr in st:\n", " assert tr.stats.starttime >= t1 - 0.00001\n", " assert tr.stats.endtime <= t2 + 0.00001\n", " assert tr.stats.station.startswith(\"O1\")\n", " assert tr.stats.channel.startswith(\"BH\")\n", " assert tr.stats.channel[-1] in {\"N\", \"E\"}\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "WaveBank also has a `get_waveforms_bulk` method for efficiently retrieving a large number of streams. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.785504Z", "iopub.status.busy": "2026-03-03T08:34:39.785321Z", "iopub.status.idle": "2026-03-03T08:34:39.844026Z", "shell.execute_reply": "2026-03-03T08:34:39.843191Z" } }, "outputs": [], "source": [ "args = [ # in practice this list may contain hundreds or thousands of requests\n", " (\n", " \"TA\",\n", " \"O15A\",\n", " \"\",\n", " \"BHZ\",\n", " t1 - 5,\n", " t2 - 5,\n", " ),\n", " (\n", " \"UU\",\n", " \"SRU\",\n", " \"\",\n", " \"HHZ\",\n", " t1,\n", " t2,\n", " ),\n", "]\n", "st = bank.get_waveforms_bulk(args)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Yield waveforms\n", "The Bank class also provides a generator for iterating large amounts of continuous waveforms. The following example shows how to get streams of one hour duration with a minute of overlap between the slices. \n", "\n", "The first step is to create a bank on a dataset which has continuous data. The example below will use the TA dataset." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.845783Z", "iopub.status.busy": "2026-03-03T08:34:39.845612Z", "iopub.status.idle": "2026-03-03T08:34:39.858943Z", "shell.execute_reply": "2026-03-03T08:34:39.858185Z" } }, "outputs": [], "source": [ "ta_bank = obsplus.WaveBank(ta_path)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:39.860763Z", "iopub.status.busy": "2026-03-03T08:34:39.860601Z", "iopub.status.idle": "2026-03-03T08:34:40.237092Z", "shell.execute_reply": "2026-03-03T08:34:40.236320Z" } }, "outputs": [], "source": [ "# get a few hours of kemmerer data\n", "ta_t1 = obspy.UTCDateTime(\"2007-02-15\")\n", "ta_t2 = obspy.UTCDateTime(\"2007-02-16\")\n", "\n", "for st in ta_bank.yield_waveforms(\n", " starttime=ta_t1, endtime=ta_t2, duration=3600, overlap=60\n", "):\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Put waveforms\n", "Files can be added to the bank by passing a stream or trace to the `bank.put_waveforms` method. `WaveBank` does not merge files so overlap in data may occur if care is not taken." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.239028Z", "iopub.status.busy": "2026-03-03T08:34:40.238864Z", "iopub.status.idle": "2026-03-03T08:34:40.283422Z", "shell.execute_reply": "2026-03-03T08:34:40.282666Z" } }, "outputs": [], "source": [ "# show that no data for RJOB is in the bank\n", "st = bank.get_waveforms(station=\"RJOB\")\n", "\n", "assert len(st) == 0\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.285512Z", "iopub.status.busy": "2026-03-03T08:34:40.285315Z", "iopub.status.idle": "2026-03-03T08:34:40.491260Z", "shell.execute_reply": "2026-03-03T08:34:40.490462Z" } }, "outputs": [], "source": [ "# add the default stream to the archive (which contains data for RJOB)\n", "bank.put_waveforms(obspy.read())\n", "st_out = bank.get_waveforms(station=\"RJOB\")\n", "\n", "# test output\n", "assert len(st_out)\n", "for tr in st_out:\n", " assert tr.stats.station == \"RJOB\"\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Availability\n", "`WaveBank` can be used to get the availability of data. The outputs can either be a dataframe or as a list of tuples in the form of [(network, station, location, channel, min_starttime, max_endtime)]. " ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.493516Z", "iopub.status.busy": "2026-03-03T08:34:40.493311Z", "iopub.status.idle": "2026-03-03T08:34:40.545724Z", "shell.execute_reply": "2026-03-03T08:34:40.545024Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
networkstationlocationchannelstarttimeendtime
0TAO15ABHE2007-08-06 01:44:38.8250002007-08-07 21:43:51.124998
1TAO16ABHE2007-08-06 01:44:38.8250002007-08-07 21:43:51.125000
2TAO18ABHE2007-08-06 01:44:38.8249982007-08-07 21:43:51.125000
3TAR16ABHE2007-08-07 02:04:54.5000002007-08-07 21:43:51.125000
4TAR17ABHE2007-08-06 01:44:38.8250002007-08-07 21:43:51.125000
\n", "
" ], "text/plain": [ " network station location channel starttime \\\n", "0 TA O15A BHE 2007-08-06 01:44:38.825000 \n", "1 TA O16A BHE 2007-08-06 01:44:38.825000 \n", "2 TA O18A BHE 2007-08-06 01:44:38.824998 \n", "3 TA R16A BHE 2007-08-07 02:04:54.500000 \n", "4 TA R17A BHE 2007-08-06 01:44:38.825000 \n", "\n", " endtime \n", "0 2007-08-07 21:43:51.124998 \n", "1 2007-08-07 21:43:51.125000 \n", "2 2007-08-07 21:43:51.125000 \n", "3 2007-08-07 21:43:51.125000 \n", "4 2007-08-07 21:43:51.125000 " ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get a dataframe of availability by seed ids and timestamps\n", "bank.get_availability_df(channel=\"BHE\", station=\"[OR]*\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.547819Z", "iopub.status.busy": "2026-03-03T08:34:40.547647Z", "iopub.status.idle": "2026-03-03T08:34:40.559906Z", "shell.execute_reply": "2026-03-03T08:34:40.559128Z" } }, "outputs": [ { "data": { "text/plain": [ "[('TA',\n", " 'O15A',\n", " '',\n", " 'BHE',\n", " 2007-08-06T01:44:38.825000Z,\n", " 2007-08-07T21:43:51.124998Z),\n", " ('TA',\n", " 'O16A',\n", " '',\n", " 'BHE',\n", " 2007-08-06T01:44:38.825000Z,\n", " 2007-08-07T21:43:51.125000Z),\n", " ('TA',\n", " 'O18A',\n", " '',\n", " 'BHE',\n", " 2007-08-06T01:44:38.824998Z,\n", " 2007-08-07T21:43:51.125000Z),\n", " ('TA',\n", " 'R16A',\n", " '',\n", " 'BHE',\n", " 2007-08-07T02:04:54.500000Z,\n", " 2007-08-07T21:43:51.125000Z),\n", " ('TA',\n", " 'R17A',\n", " '',\n", " 'BHE',\n", " 2007-08-06T01:44:38.825000Z,\n", " 2007-08-07T21:43:51.125000Z)]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get list of tuples of availability\n", "bank.availability(channel=\"BHE\", station=\"[OR]*\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Get Gaps and uptime\n", "`WaveBank` can return a dataframe of missing data with the `get_gaps_df` method, and a dataframe of reliability statistics with the `get_uptime_df` method. These are useful for assessing the completeness of an archive of contiguous data." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.561529Z", "iopub.status.busy": "2026-03-03T08:34:40.561356Z", "iopub.status.idle": "2026-03-03T08:34:40.584211Z", "shell.execute_reply": "2026-03-03T08:34:40.583542Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
networkstationlocationchannelstarttimeendtimesampling_periodpathgap_duration
0TAO16ABHE2007-08-06 01:45:48.8000002007-08-06 08:48:30.0250 days 00:00:00.025000TA.O16A..BHE__20070806T014438Z__20070806T01454...0 days 07:02:41.225000
1TAO16ABHE2007-08-06 08:49:40.0000012007-08-06 10:47:15.6000 days 00:00:00.025000TA.O16A..BHE__20070806T084830Z__20070806T08494...0 days 01:57:35.599999
2TAO16ABHE2007-08-06 10:48:25.6000002007-08-07 02:04:54.5000 days 00:00:00.025000TA.O16A..BHE__20070806T104715Z__20070806T10482...0 days 15:16:28.900000
3TAO16ABHE2007-08-07 02:06:04.4750002007-08-07 02:14:14.1000 days 00:00:00.025000TA.O16A..BHE__20070807T020454Z__20070807T02060...0 days 00:08:09.625000
4TAO16ABHE2007-08-07 02:15:24.0750002007-08-07 03:44:08.4750 days 00:00:00.025000TA.O16A..BHE__20070807T021414Z__20070807T02152...0 days 01:28:44.400000
\n", "
" ], "text/plain": [ " network station location channel starttime \\\n", "0 TA O16A BHE 2007-08-06 01:45:48.800000 \n", "1 TA O16A BHE 2007-08-06 08:49:40.000001 \n", "2 TA O16A BHE 2007-08-06 10:48:25.600000 \n", "3 TA O16A BHE 2007-08-07 02:06:04.475000 \n", "4 TA O16A BHE 2007-08-07 02:15:24.075000 \n", "\n", " endtime sampling_period \\\n", "0 2007-08-06 08:48:30.025 0 days 00:00:00.025000 \n", "1 2007-08-06 10:47:15.600 0 days 00:00:00.025000 \n", "2 2007-08-07 02:04:54.500 0 days 00:00:00.025000 \n", "3 2007-08-07 02:14:14.100 0 days 00:00:00.025000 \n", "4 2007-08-07 03:44:08.475 0 days 00:00:00.025000 \n", "\n", " path gap_duration \n", "0 TA.O16A..BHE__20070806T014438Z__20070806T01454... 0 days 07:02:41.225000 \n", "1 TA.O16A..BHE__20070806T084830Z__20070806T08494... 0 days 01:57:35.599999 \n", "2 TA.O16A..BHE__20070806T104715Z__20070806T10482... 0 days 15:16:28.900000 \n", "3 TA.O16A..BHE__20070807T020454Z__20070807T02060... 0 days 00:08:09.625000 \n", "4 TA.O16A..BHE__20070807T021414Z__20070807T02152... 0 days 01:28:44.400000 " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bank.get_gaps_df(channel=\"BHE\", station=\"O*\").head()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.585878Z", "iopub.status.busy": "2026-03-03T08:34:40.585712Z", "iopub.status.idle": "2026-03-03T08:34:40.704206Z", "shell.execute_reply": "2026-03-03T08:34:40.703519Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
networkstationlocationchannelstarttimeendtimedurationgap_durationuptimeavailability
0TAM11AVHE2007-02-15 00:00:09.9999982007-02-24 23:59:59.9999989 days 23:59:500 days9 days 23:59:501.0
1TAM11AVHN2007-02-15 00:00:09.9999982007-02-24 23:59:59.9999989 days 23:59:500 days9 days 23:59:501.0
2TAM11AVHZ2007-02-15 00:00:09.9999982007-02-24 23:59:59.9999989 days 23:59:500 days9 days 23:59:501.0
3TAM14AVHE2007-02-15 00:00:00.0000032007-02-25 00:00:00.00000310 days 00:00:000 days10 days 00:00:001.0
4TAM14AVHN2007-02-15 00:00:00.0000032007-02-25 00:00:00.00000310 days 00:00:000 days10 days 00:00:001.0
5TAM14AVHZ2007-02-15 00:00:00.0000042007-02-25 00:00:00.00000410 days 00:00:000 days10 days 00:00:001.0
\n", "
" ], "text/plain": [ " network station location channel starttime \\\n", "0 TA M11A VHE 2007-02-15 00:00:09.999998 \n", "1 TA M11A VHN 2007-02-15 00:00:09.999998 \n", "2 TA M11A VHZ 2007-02-15 00:00:09.999998 \n", "3 TA M14A VHE 2007-02-15 00:00:00.000003 \n", "4 TA M14A VHN 2007-02-15 00:00:00.000003 \n", "5 TA M14A VHZ 2007-02-15 00:00:00.000004 \n", "\n", " endtime duration gap_duration uptime \\\n", "0 2007-02-24 23:59:59.999998 9 days 23:59:50 0 days 9 days 23:59:50 \n", "1 2007-02-24 23:59:59.999998 9 days 23:59:50 0 days 9 days 23:59:50 \n", "2 2007-02-24 23:59:59.999998 9 days 23:59:50 0 days 9 days 23:59:50 \n", "3 2007-02-25 00:00:00.000003 10 days 00:00:00 0 days 10 days 00:00:00 \n", "4 2007-02-25 00:00:00.000003 10 days 00:00:00 0 days 10 days 00:00:00 \n", "5 2007-02-25 00:00:00.000004 10 days 00:00:00 0 days 10 days 00:00:00 \n", "\n", " availability \n", "0 1.0 \n", "1 1.0 \n", "2 1.0 \n", "3 1.0 \n", "4 1.0 \n", "5 1.0 " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ta_bank.get_uptime_df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Read index\n", "`WaveBank` can return a dataframe of the the index with the `read_index` method, although in most cases this shouldn't be needed." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2026-03-03T08:34:40.706136Z", "iopub.status.busy": "2026-03-03T08:34:40.705978Z", "iopub.status.idle": "2026-03-03T08:34:40.714358Z", "shell.execute_reply": "2026-03-03T08:34:40.713763Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
networkstationlocationchannelstarttimeendtimesampling_periodpath
0TAM11AVHE2007-02-21 11:59:59.9999982007-02-21 12:59:59.9999980 days 00:00:10TA/M11A/VHE/2007-02-21T12-00-00.mseed
1TAM14AVHE2007-02-21 12:00:00.0000032007-02-21 13:00:00.0000030 days 00:00:10TA/M11A/VHE/2007-02-21T12-00-00.mseed
2TAM11AVHE2007-02-19 02:59:59.9999982007-02-19 03:59:59.9999980 days 00:00:10TA/M11A/VHE/2007-02-19T03-00-00.mseed
3TAM14AVHE2007-02-19 03:00:00.0000032007-02-19 04:00:00.0000030 days 00:00:10TA/M11A/VHE/2007-02-19T03-00-00.mseed
4TAM11AVHE2007-02-22 08:59:59.9999982007-02-22 09:59:59.9999980 days 00:00:10TA/M11A/VHE/2007-02-22T09-00-00.mseed
\n", "
" ], "text/plain": [ " network station location channel starttime \\\n", "0 TA M11A VHE 2007-02-21 11:59:59.999998 \n", "1 TA M14A VHE 2007-02-21 12:00:00.000003 \n", "2 TA M11A VHE 2007-02-19 02:59:59.999998 \n", "3 TA M14A VHE 2007-02-19 03:00:00.000003 \n", "4 TA M11A VHE 2007-02-22 08:59:59.999998 \n", "\n", " endtime sampling_period \\\n", "0 2007-02-21 12:59:59.999998 0 days 00:00:10 \n", "1 2007-02-21 13:00:00.000003 0 days 00:00:10 \n", "2 2007-02-19 03:59:59.999998 0 days 00:00:10 \n", "3 2007-02-19 04:00:00.000003 0 days 00:00:10 \n", "4 2007-02-22 09:59:59.999998 0 days 00:00:10 \n", "\n", " path \n", "0 TA/M11A/VHE/2007-02-21T12-00-00.mseed \n", "1 TA/M11A/VHE/2007-02-21T12-00-00.mseed \n", "2 TA/M11A/VHE/2007-02-19T03-00-00.mseed \n", "3 TA/M11A/VHE/2007-02-19T03-00-00.mseed \n", "4 TA/M11A/VHE/2007-02-22T09-00-00.mseed " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ta_bank.read_index().head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Similar Projects\n", "`WaveBank` is a useful tool, but it may not be a good fit for every application. Check out the following items as well:\n", "\n", "Obspy has a way to visualize availability of waveform data in a directory using [obspy-scan](https://docs.obspy.org/tutorial/code_snippets/visualize_data_availability_of_local_waveform_archive.html). If you prefer a graphical option to working with `DataFrame`s this might be for you.\n", "\n", "Obspy also has [filesystem client](https://docs.obspy.org/master/packages/autogen/obspy.clients.filesystem.sds.Client.html#obspy.clients.filesystem.sds.Client) for working with SeisComP structured archives.\n", "\n", "[IRIS](https://www.iris.edu/hq/) released a mini-seed indexing program called [mseedindex](https://github.com/iris-edu/mseedindex) which has an [ObsPy API](https://github.com/obspy/obspy/pull/2206)." ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.12" } }, "nbformat": 4, "nbformat_minor": 4 }