{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "id": "wGgBzZbXuajb" }, "outputs": [], "source": [ "from collections import defaultdict\n", "import numpy as np\n", "import pandas as pd\n", "import time\n", "import requests\n", "import json\n", "import obspy\n", "from obspy.clients.fdsn import Client" ] }, { "cell_type": "markdown", "metadata": { "id": "D3rP1Gu3R8wf" }, "source": [ "## 1. Configuration" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "W98ancI1u1-T" }, "outputs": [], "source": [ "region_name = \"Ridgecrest_demo\"\n", "center = (-117.504, 35.705)\n", "horizontal_degree = 1.0\n", "vertical_degree = 1.0\n", "starttime = obspy.UTCDateTime(\"2019-07-04T17\")\n", "endtime = obspy.UTCDateTime(\"2019-07-04T18\")\n", "client = \"SCEDC\"\n", "network_list = [\"CI\"]\n", "# channel_list = \"HH*,BH*,EH*,HN*\"\n", "channel_list = \"HH*,BH*,EH*\"\n", "\n", "config = {}\n", "config[\"region\"] = region_name\n", "config[\"center\"] = center\n", "config[\"xlim_degree\"] = [center[0] - horizontal_degree / 2, center[0] + horizontal_degree / 2]\n", "config[\"ylim_degree\"] = [center[1] - vertical_degree / 2, center[1] + vertical_degree / 2]\n", "config[\"starttime\"] = starttime.datetime.isoformat()\n", "config[\"endtime\"] = endtime.datetime.isoformat()\n", "config[\"networks\"] = network_list\n", "config[\"channels\"] = channel_list\n", "config[\"client\"] = client" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'region': 'Ridgecrest_demo',\n", " 'center': (-117.504, 35.705),\n", " 'xlim_degree': [-118.004, -117.004],\n", " 'ylim_degree': [35.205, 36.205],\n", " 'starttime': '2019-07-04T17:00:00',\n", " 'endtime': '2019-07-04T18:00:00',\n", " 'networks': ['CI'],\n", " 'channels': 'HH*,BH*,EH*',\n", " 'client': 'SCEDC'}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "config" ] }, { "cell_type": "markdown", "metadata": { "id": "m6ftaZ7HSCxG" }, "source": [ "## 2. Download event information" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "DltZ-s2vtzDo" }, "outputs": [], "source": [ "events = Client(\"iris\").get_events(\n", " starttime=config[\"starttime\"],\n", " endtime=config[\"endtime\"],\n", " minlongitude=config[\"xlim_degree\"][0],\n", " maxlongitude=config[\"xlim_degree\"][1],\n", " minlatitude=config[\"ylim_degree\"][0],\n", " maxlatitude=config[\"ylim_degree\"][1],\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "gfMajl0jS82C" }, "source": [ "## 3. Download station information" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "6PaJGUf0vGHL" }, "outputs": [], "source": [ "stations = Client(config[\"client\"]).get_stations(\n", " network=\",\".join(config[\"networks\"]),\n", " station=\"*\",\n", " starttime=config[\"starttime\"],\n", " endtime=config[\"endtime\"],\n", " minlongitude=config[\"xlim_degree\"][0],\n", " maxlongitude=config[\"xlim_degree\"][1],\n", " minlatitude=config[\"ylim_degree\"][0],\n", " maxlatitude=config[\"ylim_degree\"][1],\n", " channel=config[\"channels\"],\n", " level=\"response\",\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "muvw2-CjTCPI" }, "source": [ "## 3.1 Convert station information into csv" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "id": "HZpJxfSnvVjD" }, "outputs": [], "source": [ "station_locs = defaultdict(dict)\n", "for network in stations:\n", " for station in network:\n", " for chn in station:\n", " sid = f\"{network.code}.{station.code}.{chn.location_code}.{chn.code[:-1]}\"\n", " if sid in station_locs:\n", " station_locs[sid][\"component\"] += f\",{chn.code[-1]}\"\n", " station_locs[sid][\"response\"] += f\",{chn.response.instrument_sensitivity.value:.2f}\"\n", " else:\n", " component = f\"{chn.code[-1]}\"\n", " response = f\"{chn.response.instrument_sensitivity.value:.2f}\"\n", " dtype = chn.response.instrument_sensitivity.input_units.lower()\n", " tmp_dict = {}\n", " tmp_dict[\"longitude\"], tmp_dict[\"latitude\"], tmp_dict[\"elevation_m\"] = (\n", " chn.longitude,\n", " chn.latitude,\n", " chn.elevation,\n", " )\n", " tmp_dict[\"component\"], tmp_dict[\"response\"], tmp_dict[\"unit\"] = component, response, dtype\n", " station_locs[sid] = tmp_dict\n", "\n", "station_locs = pd.DataFrame.from_dict(station_locs, orient='index')\n", "station_locs[\"station_id\"] = station_locs.index" ] }, { "cell_type": "markdown", "metadata": { "id": "5ZQdfPRgTNa8" }, "source": [ "## 4. Download waveform" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "NwfJw3f9vmyr" }, "outputs": [], "source": [ "client = Client(config[\"client\"])\n", "interval = 30 #s\n", "# interval = 3600 #s\n", "\n", "# for event in events:\n", "def downlad(event, stations):\n", " starttime = event[\"origins\"][0].time\n", " endtime = starttime + interval\n", "\n", " max_retry = 10\n", " stream = obspy.Stream()\n", " num_sta = 0\n", " for network in stations:\n", " for station in network:\n", " print(f\"********{network.code}.{station.code}********\")\n", " retry = 0\n", " while retry < max_retry:\n", " try:\n", " tmp = client.get_waveforms(\n", " network.code, station.code, \"*\", config[\"channels\"], starttime, endtime\n", " )\n", " for trace in tmp:\n", " if trace.stats.sampling_rate != 100:\n", " # print(trace)\n", " trace = trace.interpolate(100, method=\"linear\")\n", " # trace = trace.detrend(\"spline\", order=2, dspline=5*trace.stats.sampling_rate)\n", " # stream.append(trace)\n", " stream += tmp\n", " num_sta += len(tmp)\n", " break\n", " except Exception as err:\n", " print(\"Error {}.{}: {}\".format(network.code, station.code, err))\n", " message = \"No data available for request.\"\n", " if str(err)[: len(message)] == message:\n", " break\n", " retry += 1\n", " time.sleep(5)\n", " continue\n", " if retry == max_retry:\n", " print(f\"{fname}: MAX {max_retry} retries reached : {network.code}.{station.code}\")\n", "\n", " # stream.attach_response(stations)\n", " # stream = stream.remove_sensitivity()\n", " return stream" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "js21MWgZv3b9", "outputId": "c4727cff-ad03-4dc1-9980-0d29950b6e38" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "********CI.CCC********\n", "********CI.CLC********\n", "********CI.DTP********\n", "********CI.JRC2********\n", "********CI.LRL********\n", "********CI.MPM********\n", "********CI.SLA********\n", "********CI.SRT********\n", "********CI.TOW2********\n", "********CI.WBM********\n", "********CI.WCS2********\n", "********CI.WMF********\n", "********CI.WNM********\n", "********CI.WRC2********\n", "********CI.WRV2********\n", "********CI.WVP2********\n" ] } ], "source": [ "mseed = downlad(events[0], stations)" ] }, { "cell_type": "markdown", "metadata": { "id": "nZ12RlV3UlR9" }, "source": [ "## 5. Convert waveform to numpy" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "z5YUt8FN1Mxe" }, "outputs": [], "source": [ "sampling_rate = 100\n", "n_channel = 3\n", "dtype = \"float32\"\n", "amplitude = True\n", "remove_resp = True\n", "\n", "def convert_mseed(mseed, station_locs):\n", " try:\n", " mseed = mseed.detrend(\"spline\", order=2, dspline=5 * mseed[0].stats.sampling_rate)\n", " except:\n", " logging.error(f\"Error: spline detrend failed at file {fname}\")\n", " mseed = mseed.detrend(\"demean\")\n", " mseed = mseed.merge(fill_value=0)\n", " starttime = min([st.stats.starttime for st in mseed])\n", " endtime = max([st.stats.endtime for st in mseed])\n", " mseed = mseed.trim(starttime, endtime, pad=True, fill_value=0)\n", "\n", " for i in range(len(mseed)):\n", " if mseed[i].stats.sampling_rate != sampling_rate:\n", " logging.warning(\n", " f\"Resampling {mseed[i].id} from {mseed[i].stats.sampling_rate} to {sampling_rate} Hz\"\n", " )\n", " mseed[i] = mseed[i].interpolate(sampling_rate, method=\"linear\")\n", "\n", " order = ['3', '2', '1', 'E', 'N', 'Z']\n", " order = {key: i for i, key in enumerate(order)}\n", " comp2idx = {\"3\": 0, \"2\": 1, \"1\": 2, \"E\": 0, \"N\": 1, \"Z\": 2}\n", "\n", " nsta = len(station_locs)\n", " nt = max(len(mseed[i].data) for i in range(len(mseed)))\n", " data = []\n", " station_id = []\n", " t0 = []\n", " for i in range(nsta):\n", " trace_data = np.zeros([nt, n_channel], dtype=dtype)\n", " empty_station = True\n", " # sta = station_locs.iloc[i][\"station\"]\n", " sta = station_locs.index[i]\n", " comp = station_locs.iloc[i][\"component\"].split(\",\")\n", " if remove_resp:\n", " resp = station_locs.iloc[i][\"response\"].split(\",\")\n", " # resp = station_locs.iloc[i][\"response\"]\n", "\n", " for j, c in enumerate(sorted(comp, key=lambda x: order[x[-1]])):\n", "\n", " resp_j = float(resp[j])\n", " if len(comp) != 3: ## less than 3 component\n", " j = comp2idx[c]\n", "\n", " if len(mseed.select(id=sta + c)) == 0:\n", " print(f\"Empty trace: {sta+c} {starttime}\")\n", " continue\n", " else:\n", " empty_station = False\n", "\n", " tmp = mseed.select(id=sta + c)[0].data.astype(dtype)\n", " trace_data[: len(tmp), j] = tmp[:nt]\n", "\n", " if station_locs.iloc[i][\"unit\"] == \"m/s**2\":\n", " tmp = mseed.select(id=sta + c)[0]\n", " tmp = tmp.integrate()\n", " tmp = tmp.filter(\"highpass\", freq=1.0)\n", " tmp = tmp.data.astype(dtype)\n", " trace_data[: len(tmp), j] = tmp[:nt]\n", " elif station_locs.iloc[i][\"unit\"] == \"m/s\":\n", " tmp = mseed.select(id=sta + c)[0].data.astype(dtype)\n", " trace_data[: len(tmp), j] = tmp[:nt]\n", " else:\n", " print(\n", " f\"Error in {station_locs.iloc[i]['station']}\\n{station_locs.iloc[i]['unit']} should be m/s**2 or m/s!\"\n", " )\n", "\n", " if remove_resp:\n", " trace_data[:, j] /= resp_j\n", "\n", " if not empty_station:\n", " data.append(trace_data)\n", " station_id.append(sta)\n", " t0.append(starttime.strftime(\"%Y-%m-%dT%H:%M:%S.%f\")[:-3])\n", "\n", " data = np.stack(data)\n", "\n", " meta = {\"data\": data, \"t0\": t0, \"station_id\": station_id, \"fname\": station_id}\n", "\n", "\n", " return meta" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "hNaM-pt7VEev" }, "outputs": [], "source": [ "meta = convert_mseed(mseed, station_locs)" ] }, { "cell_type": "markdown", "metadata": { "id": "3dpQquouVKya" }, "source": [ "## 6. Pick P/S picks using PhaseNet" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 408 }, "id": "UDPpI9rl02Kv", "outputId": "acdd4ebc-82c3-4549-ce15-581c82afafc4" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PhaseNet picks station_id phase_time phase_score phase_type dt\n", "0 CI.CCC..BH 2019-07-04T17:58:07.368 0.952 P 0.01\n", "1 CI.CCC..BH 2019-07-04T17:58:10.978 0.891 S 0.01\n", "2 CI.CCC..HH 2019-07-04T17:58:07.398 0.952 P 0.01\n", "3 CI.CCC..HH 2019-07-04T17:58:11.008 0.798 S 0.01\n", "4 CI.CLC..BH 2019-07-04T17:58:05.478 0.959 P 0.01\n", ".. ... ... ... ... ...\n", "57 CI.WRC2..HH 2019-07-04T17:58:08.038 0.983 P 0.01\n", "58 CI.WRC2..HH 2019-07-04T17:58:12.048 0.803 S 0.01\n", "59 CI.WRV2..EH 2019-07-04T17:58:10.948 0.959 P 0.01\n", "60 CI.WRV2..EH 2019-07-04T17:58:17.068 0.551 S 0.01\n", "61 CI.WVP2..EH 2019-07-04T17:58:09.578 0.352 P 0.01\n", "\n", "[62 rows x 5 columns]\n" ] } ], "source": [ "# PHASENET_API_URL = \"http://127.0.0.1:8000\"\n", "PHASENET_API_URL = \"https://ai4eps-eqnet.hf.space\"\n", "\n", "\n", "batch = 4\n", "phasenet_picks = []\n", "for j in range(0, len(meta[\"station_id\"]), batch):\n", " req = {\"id\": [[x] for x in meta[\"station_id\"][j:j+batch]],\n", " \"timestamp\": meta[\"t0\"][j:j+batch],\n", " \"vec\": meta[\"data\"][j:j+batch].tolist()}\n", "\n", " resp = requests.post(f'{PHASENET_API_URL}/predict', json=req)\n", " phasenet_picks.extend(resp.json())\n", "\n", "print('PhaseNet picks', pd.DataFrame(phasenet_picks))\n" ] }, { "cell_type": "markdown", "metadata": { "id": "5JX6AppkV1b0" }, "source": [ "## 7. Associate picks using GaMMA" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 228 }, "id": "YEkupkaa3JmD", "outputId": "9b40951c-ed12-4031-ddbc-7ada6c4e09e5" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GaMMA catalog:\n" ] }, { "data": { "text/html": [ "
\n", " | time | \n", "magnitude | \n", "sigma_time | \n", "sigma_amp | \n", "cov_time_amp | \n", "gamma_score | \n", "num_picks | \n", "num_p_picks | \n", "num_s_picks | \n", "event_index | \n", "longitude | \n", "latitude | \n", "depth_km | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "2019-07-04T17:58:02.566 | \n", "999 | \n", "0.344259 | \n", "0 | \n", "0 | \n", "56.970255 | \n", "57 | \n", "29 | \n", "28 | \n", "1 | \n", "-117.503559 | \n", "35.70536 | \n", "12.578723 | \n", "
\n", " | station_id | \n", "phase_time | \n", "phase_score | \n", "phase_type | \n", "dt | \n", "event_index | \n", "gamma_score | \n", "
---|---|---|---|---|---|---|---|
0 | \n", "CI.CCC..BH | \n", "2019-07-04T17:58:07.368000 | \n", "0.952 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.667284 | \n", "
1 | \n", "CI.CCC..BH | \n", "2019-07-04T17:58:10.978000 | \n", "0.891 | \n", "S | \n", "0.01 | \n", "1 | \n", "0.362202 | \n", "
2 | \n", "CI.CCC..HH | \n", "2019-07-04T17:58:07.398000 | \n", "0.952 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.631032 | \n", "
3 | \n", "CI.CCC..HH | \n", "2019-07-04T17:58:11.008000 | \n", "0.798 | \n", "S | \n", "0.01 | \n", "1 | \n", "0.294299 | \n", "
4 | \n", "CI.CLC..BH | \n", "2019-07-04T17:58:05.478000 | \n", "0.959 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.491822 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "... | \n", "
57 | \n", "CI.WRC2..HH | \n", "2019-07-04T17:58:08.038000 | \n", "0.983 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.617376 | \n", "
58 | \n", "CI.WRC2..HH | \n", "2019-07-04T17:58:12.048000 | \n", "0.803 | \n", "S | \n", "0.01 | \n", "1 | \n", "0.859684 | \n", "
59 | \n", "CI.WRV2..EH | \n", "2019-07-04T17:58:10.948000 | \n", "0.959 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.573461 | \n", "
60 | \n", "CI.WRV2..EH | \n", "2019-07-04T17:58:17.068000 | \n", "0.551 | \n", "S | \n", "0.01 | \n", "1 | \n", "0.877037 | \n", "
61 | \n", "CI.WVP2..EH | \n", "2019-07-04T17:58:09.578000 | \n", "0.352 | \n", "P | \n", "0.01 | \n", "1 | \n", "0.676099 | \n", "
62 rows × 7 columns
\n", "