crimeacs commited on
Commit
68d65f8
1 Parent(s): 9f6fe0d

updated layout

Browse files
Files changed (27) hide show
  1. Gradio_app.ipynb +204 -60
  2. app.py +71 -56
  3. data/cached/BK_MCCM_2023-04-01T16:43:30.541616Z.mseed +0 -0
  4. data/cached/BK_SAO_2023-04-01T16:43:36.718558Z.mseed +0 -0
  5. data/cached/NC_C006_2023-04-01T16:43:22.900707Z.mseed +0 -0
  6. data/cached/NC_C031_2023-04-01T16:43:22.656861Z.mseed +0 -0
  7. data/cached/NC_C050_2023-04-01T16:43:24.524689Z.mseed +0 -0
  8. data/cached/NC_C055_2023-04-01T16:43:24.930990Z.mseed +0 -0
  9. data/cached/NC_C056_2023-04-01T16:43:22.066458Z.mseed +0 -0
  10. data/cached/NC_G004_2023-04-01T16:43:40.683359Z.mseed +0 -0
  11. data/cached/NC_J010_2023-04-01T16:43:25.779606Z.mseed +0 -0
  12. data/cached/NC_J068_2023-04-01T16:43:26.681315Z.mseed +0 -0
  13. data/cached/NC_RWSVT_2023-04-01T16:43:23.543745Z.mseed +0 -0
  14. data/cached/PB_B054_2023-04-01T16:43:22.147061Z.mseed +0 -0
  15. data/cached/PB_B057_2023-04-01T16:43:26.668494Z.mseed +0 -0
  16. data/cached/PB_B058_2023-04-01T16:43:35.559392Z.mseed +0 -0
  17. data/cached/PB_B065_2023-04-01T16:43:36.828013Z.mseed +0 -0
  18. data/cached/PB_B066_2023-04-01T16:43:34.748830Z.mseed +0 -0
  19. data/cached/PB_B067_2023-04-01T16:43:36.084437Z.mseed +0 -0
  20. data/cached/PB_P176_2023-04-01T16:43:25.099350Z.mseed +0 -0
  21. data/cached/PB_P181_2023-04-01T16:43:23.984589Z.mseed +0 -0
  22. data/cached/PB_P197_2023-04-01T16:43:32.497268Z.mseed +0 -0
  23. data/cached/PB_P199_2023-04-01T16:43:28.886780Z.mseed +0 -0
  24. data/cached/PB_P201_2023-04-01T16:43:33.477717Z.mseed +0 -0
  25. data/cached/PB_P224_2023-04-01T16:43:22.286686Z.mseed +0 -0
  26. data/cached/PB_P248_2023-04-01T16:43:24.960417Z.mseed +0 -0
  27. data/cached/PB_P262_2023-04-01T16:43:24.445973Z.mseed +0 -0
Gradio_app.ipynb CHANGED
@@ -2,14 +2,14 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 66,
6
  "metadata": {},
7
  "outputs": [
8
  {
9
  "name": "stdout",
10
  "output_type": "stream",
11
  "text": [
12
- "Running on local URL: http://127.0.0.1:7906\n",
13
  "\n",
14
  "To create a public link, set `share=True` in `launch()`.\n"
15
  ]
@@ -17,7 +17,7 @@
17
  {
18
  "data": {
19
  "text/html": [
20
- "<div><iframe src=\"http://127.0.0.1:7906/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
21
  ],
22
  "text/plain": [
23
  "<IPython.core.display.HTML object>"
@@ -30,9 +30,138 @@
30
  "data": {
31
  "text/plain": []
32
  },
33
- "execution_count": 66,
34
  "metadata": {},
35
  "output_type": "execute_result"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
  ],
38
  "source": [
@@ -153,7 +282,7 @@
153
  " return coeff\n",
154
  "\n",
155
  "def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source_depth_km, velocity_model, max_waveforms):\n",
156
- " distances, t0s, st_lats, st_lons, waveforms = [], [], [], [], []\n",
157
  " \n",
158
  " taup_model = TauPyModel(model=velocity_model)\n",
159
  " client = Client(client_name)\n",
@@ -235,6 +364,7 @@
235
  " st_lats.append(station.latitude)\n",
236
  " st_lons.append(station.longitude)\n",
237
  " waveforms.append(waveform)\n",
 
238
  "\n",
239
  " print(f\"Added {network.code}.{station.code} to the list of waveforms\")\n",
240
  "\n",
@@ -264,6 +394,7 @@
264
  " t0s = np.array(t0s)[selection_indexes]\n",
265
  " st_lats = np.array(st_lats)[selection_indexes]\n",
266
  " st_lons = np.array(st_lons)[selection_indexes]\n",
 
267
  "\n",
268
  " waveforms = [torch.tensor(waveform) for waveform in waveforms]\n",
269
  "\n",
@@ -302,6 +433,11 @@
302
  " topo_map.da.plot(ax = ax[2], cmap='Greys', add_colorbar=False, add_labels=False)\n",
303
  " ax[1].imshow(hillshade, cmap=\"Greys\", alpha=0.5)\n",
304
  "\n",
 
 
 
 
 
305
  " for i in range(len(waveforms)):\n",
306
  " print(f\"Plotting waveform {i+1}/{len(waveforms)}\")\n",
307
  " current_P = p_phases[i::len(waveforms)]\n",
@@ -329,6 +465,11 @@
329
  " velocity_s = (distances[i]*111.2)/(delta_t+current_S.mean()*60).item()\n",
330
  "\n",
331
  " print(f\"Station {st_lats[i]}, {st_lons[i]} has P velocity {velocity_p} and S velocity {velocity_s}\")\n",
 
 
 
 
 
332
  " \n",
333
  " # Generate an array from st_lat to eq_lat and from st_lon to eq_lon\n",
334
  " x = np.linspace(st_lons[i], eq_lon, 50)\n",
@@ -357,15 +498,13 @@
357
  " cbar.set_label('S Velocity (km/s)')\n",
358
  " ax[2].set_title('S Velocity')\n",
359
  "\n",
360
- "\n",
361
- "\n",
362
  " plt.subplots_adjust(hspace=0., wspace=0.5)\n",
363
  "\n",
364
  " fig.canvas.draw();\n",
365
  " image = np.array(fig.canvas.renderer.buffer_rgba())\n",
366
  " plt.close(fig)\n",
367
  "\n",
368
- " return image\n",
369
  "\n",
370
  "\n",
371
  "model = Onset_picker.load_from_checkpoint(\"./weights.ckpt\",\n",
@@ -412,75 +551,80 @@
412
  " with gr.Tab(\"Select earthquake from catalogue\"):\n",
413
  " gr.Markdown(\"\"\"Select an earthquake from the global earthquake catalogue and the app will download the waveform from the FDSN client of your choice.\n",
414
  " \"\"\")\n",
415
- " \n",
416
- " client_inputs = gr.Dropdown(\n",
417
- " choices = list(URL_MAPPINGS.keys()), \n",
418
- " label=\"FDSN Client\", \n",
419
- " info=\"Select one of the available FDSN clients\",\n",
420
- " value = \"IRIS\",\n",
421
- " interactive=True\n",
422
- " )\n",
423
- "\n",
424
  " with gr.Row(): \n",
 
 
 
 
 
 
 
425
  "\n",
426
- " timestamp_inputs = gr.Textbox(value='2019-07-04 17:33:49',\n",
427
- " placeholder='YYYY-MM-DD HH:MM:SS',\n",
428
- " label=\"Timestamp\",\n",
429
- " info=\"Timestamp of the earthquake\",\n",
430
- " max_lines=1,\n",
431
- " interactive=True)\n",
432
- " \n",
433
- " eq_lat_inputs = gr.Number(value=35.766, \n",
434
- " label=\"Latitude\", \n",
435
- " info=\"Latitude of the earthquake\",\n",
436
- " interactive=True)\n",
437
- " \n",
438
- " eq_lon_inputs = gr.Number(value=-117.605,\n",
439
- " label=\"Longitude\",\n",
440
- " info=\"Longitude of the earthquake\",\n",
441
- " interactive=True)\n",
442
- " \n",
443
- " source_depth_inputs = gr.Number(value=10,\n",
444
- " label=\"Source depth (km)\",\n",
445
- " info=\"Depth of the earthquake\",\n",
446
- " interactive=True)\n",
447
- " \n",
448
- " radius_inputs = gr.Slider(minimum=1, \n",
449
- " maximum=150, \n",
450
- " value=50, label=\"Radius (km)\", \n",
451
- " step=10,\n",
452
- " info=\"\"\"Select the radius around the earthquake to download data from.\\n \n",
453
- " Note that the larger the radius, the longer the app will take to run.\"\"\",\n",
454
- " interactive=True)\n",
455
- " \n",
456
  " velocity_inputs = gr.Dropdown(\n",
457
  " choices = ['1066a', '1066b', 'ak135', \n",
458
- " 'ak135f', 'herrin', 'iasp91', \n",
459
- " 'jb', 'prem', 'pwdk'], \n",
460
  " label=\"1D velocity model\", \n",
461
  " info=\"Velocity model for station selection\",\n",
462
  " value = \"1066a\",\n",
463
  " interactive=True\n",
464
  " )\n",
465
  "\n",
466
- " max_waveforms_inputs = gr.Slider(minimum=1,\n",
467
- " maximum=100,\n",
468
- " value=10,\n",
469
- " label=\"Max waveforms per section\",\n",
470
- " step=1,\n",
471
- " info=\"Maximum number of waveforms to show per section\\n (to avoid long prediction times)\",\n",
472
- " interactive=True,\n",
473
- " )\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
  " \n",
475
  " button = gr.Button(\"Predict phases\")\n",
476
- " outputs_section = gr.Image(label='Waveforms with Phases Marked', type='numpy', interactive=False)\n",
477
- " \n",
 
478
  " button.click(predict_on_section, \n",
479
  " inputs=[client_inputs, timestamp_inputs, \n",
480
  " eq_lat_inputs, eq_lon_inputs, \n",
481
  " radius_inputs, source_depth_inputs, \n",
482
  " velocity_inputs, max_waveforms_inputs],\n",
483
- " outputs=outputs_section)\n",
484
  "\n",
485
  "demo.launch()"
486
  ]
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 83,
6
  "metadata": {},
7
  "outputs": [
8
  {
9
  "name": "stdout",
10
  "output_type": "stream",
11
  "text": [
12
+ "Running on local URL: http://127.0.0.1:7923\n",
13
  "\n",
14
  "To create a public link, set `share=True` in `launch()`.\n"
15
  ]
 
17
  {
18
  "data": {
19
  "text/html": [
20
+ "<div><iframe src=\"http://127.0.0.1:7923/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
21
  ],
22
  "text/plain": [
23
  "<IPython.core.display.HTML object>"
 
30
  "data": {
31
  "text/plain": []
32
  },
33
+ "execution_count": 83,
34
  "metadata": {},
35
  "output_type": "execute_result"
36
+ },
37
+ {
38
+ "name": "stdout",
39
+ "output_type": "stream",
40
+ "text": [
41
+ "Starting to download inventory\n",
42
+ "Finished downloading inventory\n",
43
+ "Processing CI.CCC...\n",
44
+ "Downloading waveform\n",
45
+ "Skipping CI_CCC_2019-07-04T17:33:40.494920Z\n",
46
+ "Processing CI.CLC...\n",
47
+ "Processing CI.JRC2...\n",
48
+ "Reading cached waveform\n",
49
+ "Added CI.JRC2 to the list of waveforms\n",
50
+ "Processing CI.LRL...\n",
51
+ "Reading cached waveform\n",
52
+ "Added CI.LRL to the list of waveforms\n",
53
+ "Processing CI.MPM...\n",
54
+ "Reading cached waveform\n",
55
+ "Processing CI.Q0072...\n",
56
+ "Reading cached waveform\n",
57
+ "Processing CI.SLA...\n",
58
+ "Reading cached waveform\n",
59
+ "Added CI.SLA to the list of waveforms\n",
60
+ "Processing CI.SRT...\n",
61
+ "Reading cached waveform\n",
62
+ "Added CI.SRT to the list of waveforms\n",
63
+ "Processing CI.TOW2...\n",
64
+ "Reading cached waveform\n",
65
+ "Added CI.TOW2 to the list of waveforms\n",
66
+ "Processing CI.WBM...\n",
67
+ "Downloading waveform\n",
68
+ "Skipping CI_WBM_2019-07-04T17:33:40.063616Z\n",
69
+ "Processing CI.WCS2...\n",
70
+ "Downloading waveform\n",
71
+ "Skipping CI_WCS2_2019-07-04T17:33:40.200958Z\n",
72
+ "Processing CI.WMF...\n",
73
+ "Reading cached waveform\n",
74
+ "Added CI.WMF to the list of waveforms\n",
75
+ "Processing CI.WNM...\n",
76
+ "Reading cached waveform\n",
77
+ "Processing CI.WRC2...\n",
78
+ "Downloading waveform\n",
79
+ "Skipping CI_WRC2_2019-07-04T17:33:38.698099Z\n",
80
+ "Processing CI.WRV2...\n",
81
+ "Reading cached waveform\n",
82
+ "Processing CI.WVP2...\n",
83
+ "Downloading waveform\n",
84
+ "Skipping CI_WVP2_2019-07-04T17:33:39.650402Z\n",
85
+ "Processing NP.1809...\n",
86
+ "Reading cached waveform\n",
87
+ "Processing NP.5419...\n",
88
+ "Reading cached waveform\n",
89
+ "Processing PB.B916...\n",
90
+ "Reading cached waveform\n",
91
+ "Processing PB.B917...\n",
92
+ "Reading cached waveform\n",
93
+ "Processing PB.B918...\n",
94
+ "Reading cached waveform\n",
95
+ "Processing PB.B921...\n",
96
+ "Reading cached waveform\n",
97
+ "Starting to run predictions\n"
98
+ ]
99
+ },
100
+ {
101
+ "name": "stderr",
102
+ "output_type": "stream",
103
+ "text": [
104
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:225: FutureWarning: The input object of type 'Tensor' is an array-like implementing one of the corresponding protocols (`__array__`, `__array_interface__` or `__array_struct__`); but not a sequence (or 0-D). In the future, this object will be coerced as if it was first converted using `np.array(obj)`. To retain the old behaviour, you have to either modify the type 'Tensor', or assign to an empty array created with `np.empty(correct_shape, dtype=object)`.\n",
105
+ " waveforms = np.array(waveforms)[selection_indexes]\n",
106
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:225: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.\n",
107
+ " waveforms = np.array(waveforms)[selection_indexes]\n",
108
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:232: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
109
+ " waveforms = [torch.tensor(waveform) for waveform in waveforms]\n"
110
+ ]
111
+ },
112
+ {
113
+ "name": "stdout",
114
+ "output_type": "stream",
115
+ "text": [
116
+ "Starting plotting 3 waveforms\n",
117
+ "Fetching topography\n",
118
+ "Plotting topo\n"
119
+ ]
120
+ },
121
+ {
122
+ "name": "stderr",
123
+ "output_type": "stream",
124
+ "text": [
125
+ "/Users/anovosel/miniconda3/envs/phasehunter/lib/python3.11/site-packages/bmi_topography/api_key.py:49: UserWarning: You are using a demo key to fetch data from OpenTopography, functionality will be limited. See https://bmi-topography.readthedocs.io/en/latest/#api-key for more information.\n",
126
+ " warnings.warn(\n"
127
+ ]
128
+ },
129
+ {
130
+ "name": "stdout",
131
+ "output_type": "stream",
132
+ "text": [
133
+ "Plotting waveform 1/3\n",
134
+ "Station 36.11758, -117.85486 has P velocity 4.96342368856812 and S velocity 3.0001093626503503\n",
135
+ "Plotting waveform 2/3\n"
136
+ ]
137
+ },
138
+ {
139
+ "name": "stderr",
140
+ "output_type": "stream",
141
+ "text": [
142
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:302: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
143
+ " output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], 'starttime' : [str(t0s[i])],\n"
144
+ ]
145
+ },
146
+ {
147
+ "name": "stdout",
148
+ "output_type": "stream",
149
+ "text": [
150
+ "Station 35.98249, -117.80885 has P velocity 4.229153346955616 and S velocity 2.3118595983254937\n",
151
+ "Plotting waveform 3/3\n",
152
+ "Station 35.69235, -117.75051 has P velocity 2.9537452996413585 and S velocity 1.3863453902284213\n",
153
+ "Plotting stations\n"
154
+ ]
155
+ },
156
+ {
157
+ "name": "stderr",
158
+ "output_type": "stream",
159
+ "text": [
160
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:302: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
161
+ " output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], 'starttime' : [str(t0s[i])],\n",
162
+ "/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_17878/2982466024.py:302: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
163
+ " output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], 'starttime' : [str(t0s[i])],\n"
164
+ ]
165
  }
166
  ],
167
  "source": [
 
282
  " return coeff\n",
283
  "\n",
284
  "def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source_depth_km, velocity_model, max_waveforms):\n",
285
+ " distances, t0s, st_lats, st_lons, waveforms, names = [], [], [], [], [], []\n",
286
  " \n",
287
  " taup_model = TauPyModel(model=velocity_model)\n",
288
  " client = Client(client_name)\n",
 
364
  " st_lats.append(station.latitude)\n",
365
  " st_lons.append(station.longitude)\n",
366
  " waveforms.append(waveform)\n",
367
+ " names.append(f\"{network.code}.{station.code}\")\n",
368
  "\n",
369
  " print(f\"Added {network.code}.{station.code} to the list of waveforms\")\n",
370
  "\n",
 
394
  " t0s = np.array(t0s)[selection_indexes]\n",
395
  " st_lats = np.array(st_lats)[selection_indexes]\n",
396
  " st_lons = np.array(st_lons)[selection_indexes]\n",
397
+ " names = np.array(names)[selection_indexes]\n",
398
  "\n",
399
  " waveforms = [torch.tensor(waveform) for waveform in waveforms]\n",
400
  "\n",
 
433
  " topo_map.da.plot(ax = ax[2], cmap='Greys', add_colorbar=False, add_labels=False)\n",
434
  " ax[1].imshow(hillshade, cmap=\"Greys\", alpha=0.5)\n",
435
  "\n",
436
+ " output_picks = pd.DataFrame({'station_name' : [], 'starttime' : [], \n",
437
+ " 'p_phase' : [], 'p_uncertainty' : [], 's_phase' : [], 's_uncertainty' : [],\n",
438
+ " 'velocity_p' : [], 'velocity_s' : []})\n",
439
+ " \n",
440
+ " \n",
441
  " for i in range(len(waveforms)):\n",
442
  " print(f\"Plotting waveform {i+1}/{len(waveforms)}\")\n",
443
  " current_P = p_phases[i::len(waveforms)]\n",
 
465
  " velocity_s = (distances[i]*111.2)/(delta_t+current_S.mean()*60).item()\n",
466
  "\n",
467
  " print(f\"Station {st_lats[i]}, {st_lons[i]} has P velocity {velocity_p} and S velocity {velocity_s}\")\n",
468
+ "\n",
469
+ " output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], 'starttime' : [str(t0s[i])], \n",
470
+ " 'p_phase' : [(delta_t+current_P.mean()*60).item()], 'p_uncertainty' : [current_P.std().item()*60], \n",
471
+ " 's_phase' : [(delta_t+current_S.mean()*60).item()], 's_uncertainty' : [current_S.std().item()*60],\n",
472
+ " 'velocity_p' : [velocity_p], 'velocity_s' : [velocity_s]}))\n",
473
  " \n",
474
  " # Generate an array from st_lat to eq_lat and from st_lon to eq_lon\n",
475
  " x = np.linspace(st_lons[i], eq_lon, 50)\n",
 
498
  " cbar.set_label('S Velocity (km/s)')\n",
499
  " ax[2].set_title('S Velocity')\n",
500
  "\n",
 
 
501
  " plt.subplots_adjust(hspace=0., wspace=0.5)\n",
502
  "\n",
503
  " fig.canvas.draw();\n",
504
  " image = np.array(fig.canvas.renderer.buffer_rgba())\n",
505
  " plt.close(fig)\n",
506
  "\n",
507
+ " return image, output_picks\n",
508
  "\n",
509
  "\n",
510
  "model = Onset_picker.load_from_checkpoint(\"./weights.ckpt\",\n",
 
551
  " with gr.Tab(\"Select earthquake from catalogue\"):\n",
552
  " gr.Markdown(\"\"\"Select an earthquake from the global earthquake catalogue and the app will download the waveform from the FDSN client of your choice.\n",
553
  " \"\"\")\n",
 
 
 
 
 
 
 
 
 
554
  " with gr.Row(): \n",
555
+ " client_inputs = gr.Dropdown(\n",
556
+ " choices = list(URL_MAPPINGS.keys()), \n",
557
+ " label=\"FDSN Client\", \n",
558
+ " info=\"Select one of the available FDSN clients\",\n",
559
+ " value = \"IRIS\",\n",
560
+ " interactive=True\n",
561
+ " )\n",
562
  "\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  " velocity_inputs = gr.Dropdown(\n",
564
  " choices = ['1066a', '1066b', 'ak135', \n",
565
+ " 'ak135f', 'herrin', 'iasp91', \n",
566
+ " 'jb', 'prem', 'pwdk'], \n",
567
  " label=\"1D velocity model\", \n",
568
  " info=\"Velocity model for station selection\",\n",
569
  " value = \"1066a\",\n",
570
  " interactive=True\n",
571
  " )\n",
572
  "\n",
573
+ " with gr.Column(scale=4):\n",
574
+ " with gr.Row(): \n",
575
+ " timestamp_inputs = gr.Textbox(value='2019-07-04 17:33:49',\n",
576
+ " placeholder='YYYY-MM-DD HH:MM:SS',\n",
577
+ " label=\"Timestamp\",\n",
578
+ " info=\"Timestamp of the earthquake\",\n",
579
+ " max_lines=1,\n",
580
+ " interactive=True)\n",
581
+ " \n",
582
+ " eq_lat_inputs = gr.Number(value=35.766, \n",
583
+ " label=\"Latitude\", \n",
584
+ " info=\"Latitude of the earthquake\",\n",
585
+ " interactive=True)\n",
586
+ " \n",
587
+ " eq_lon_inputs = gr.Number(value=-117.605,\n",
588
+ " label=\"Longitude\",\n",
589
+ " info=\"Longitude of the earthquake\",\n",
590
+ " interactive=True)\n",
591
+ " \n",
592
+ " source_depth_inputs = gr.Number(value=10,\n",
593
+ " label=\"Source depth (km)\",\n",
594
+ " info=\"Depth of the earthquake\",\n",
595
+ " interactive=True)\n",
596
+ " \n",
597
+ "\n",
598
+ " \n",
599
+ " with gr.Column(scale=2):\n",
600
+ " with gr.Row(): \n",
601
+ " radius_inputs = gr.Slider(minimum=1, \n",
602
+ " maximum=150, \n",
603
+ " value=50, label=\"Radius (km)\", \n",
604
+ " step=10,\n",
605
+ " info=\"\"\"Select the radius around the earthquake to download data from.\\n \n",
606
+ " Note that the larger the radius, the longer the app will take to run.\"\"\",\n",
607
+ " interactive=True)\n",
608
+ " \n",
609
+ " max_waveforms_inputs = gr.Slider(minimum=1,\n",
610
+ " maximum=100,\n",
611
+ " value=10,\n",
612
+ " label=\"Max waveforms per section\",\n",
613
+ " step=1,\n",
614
+ " info=\"Maximum number of waveforms to show per section\\n (to avoid long prediction times)\",\n",
615
+ " interactive=True,\n",
616
+ " )\n",
617
  " \n",
618
  " button = gr.Button(\"Predict phases\")\n",
619
+ " output_image = gr.Image(label='Waveforms with Phases Marked', type='numpy', interactive=False)\n",
620
+ " output_picks = gr.Dataframe(label='# Pick data', type='pandas', interactive=False)\n",
621
+ "\n",
622
  " button.click(predict_on_section, \n",
623
  " inputs=[client_inputs, timestamp_inputs, \n",
624
  " eq_lat_inputs, eq_lon_inputs, \n",
625
  " radius_inputs, source_depth_inputs, \n",
626
  " velocity_inputs, max_waveforms_inputs],\n",
627
+ " outputs=[output_image, output_picks])\n",
628
  "\n",
629
  "demo.launch()"
630
  ]
app.py CHANGED
@@ -115,7 +115,7 @@ def variance_coefficient(residuals):
115
  return coeff
116
 
117
  def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source_depth_km, velocity_model, max_waveforms):
118
- distances, t0s, st_lats, st_lons, waveforms = [], [], [], [], []
119
 
120
  taup_model = TauPyModel(model=velocity_model)
121
  client = Client(client_name)
@@ -197,6 +197,7 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
197
  st_lats.append(station.latitude)
198
  st_lons.append(station.longitude)
199
  waveforms.append(waveform)
 
200
 
201
  print(f"Added {network.code}.{station.code} to the list of waveforms")
202
 
@@ -226,6 +227,7 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
226
  t0s = np.array(t0s)[selection_indexes]
227
  st_lats = np.array(st_lats)[selection_indexes]
228
  st_lons = np.array(st_lons)[selection_indexes]
 
229
 
230
  waveforms = [torch.tensor(waveform) for waveform in waveforms]
231
 
@@ -264,6 +266,11 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
264
  topo_map.da.plot(ax = ax[2], cmap='Greys', add_colorbar=False, add_labels=False)
265
  ax[1].imshow(hillshade, cmap="Greys", alpha=0.5)
266
 
 
 
 
 
 
267
  for i in range(len(waveforms)):
268
  print(f"Plotting waveform {i+1}/{len(waveforms)}")
269
  current_P = p_phases[i::len(waveforms)]
@@ -291,6 +298,11 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
291
  velocity_s = (distances[i]*111.2)/(delta_t+current_S.mean()*60).item()
292
 
293
  print(f"Station {st_lats[i]}, {st_lons[i]} has P velocity {velocity_p} and S velocity {velocity_s}")
 
 
 
 
 
294
 
295
  # Generate an array from st_lat to eq_lat and from st_lon to eq_lon
296
  x = np.linspace(st_lons[i], eq_lon, 50)
@@ -319,15 +331,13 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
319
  cbar.set_label('S Velocity (km/s)')
320
  ax[2].set_title('S Velocity')
321
 
322
-
323
-
324
  plt.subplots_adjust(hspace=0., wspace=0.5)
325
 
326
  fig.canvas.draw();
327
  image = np.array(fig.canvas.renderer.buffer_rgba())
328
  plt.close(fig)
329
 
330
- return image
331
 
332
 
333
  model = Onset_picker.load_from_checkpoint("./weights.ckpt",
@@ -374,74 +384,79 @@ with gr.Blocks() as demo:
374
  with gr.Tab("Select earthquake from catalogue"):
375
  gr.Markdown("""Select an earthquake from the global earthquake catalogue and the app will download the waveform from the FDSN client of your choice.
376
  """)
377
-
378
- client_inputs = gr.Dropdown(
379
- choices = list(URL_MAPPINGS.keys()),
380
- label="FDSN Client",
381
- info="Select one of the available FDSN clients",
382
- value = "IRIS",
383
- interactive=True
384
- )
385
-
386
  with gr.Row():
 
 
 
 
 
 
 
387
 
388
- timestamp_inputs = gr.Textbox(value='2019-07-04 17:33:49',
389
- placeholder='YYYY-MM-DD HH:MM:SS',
390
- label="Timestamp",
391
- info="Timestamp of the earthquake",
392
- max_lines=1,
393
- interactive=True)
394
-
395
- eq_lat_inputs = gr.Number(value=35.766,
396
- label="Latitude",
397
- info="Latitude of the earthquake",
398
- interactive=True)
399
-
400
- eq_lon_inputs = gr.Number(value=-117.605,
401
- label="Longitude",
402
- info="Longitude of the earthquake",
403
- interactive=True)
404
-
405
- source_depth_inputs = gr.Number(value=10,
406
- label="Source depth (km)",
407
- info="Depth of the earthquake",
408
- interactive=True)
409
-
410
- radius_inputs = gr.Slider(minimum=1,
411
- maximum=150,
412
- value=50, label="Radius (km)",
413
- step=10,
414
- info="""Select the radius around the earthquake to download data from.\n
415
- Note that the larger the radius, the longer the app will take to run.""",
416
- interactive=True)
417
-
418
  velocity_inputs = gr.Dropdown(
419
  choices = ['1066a', '1066b', 'ak135',
420
- 'ak135f', 'herrin', 'iasp91',
421
- 'jb', 'prem', 'pwdk'],
422
  label="1D velocity model",
423
  info="Velocity model for station selection",
424
  value = "1066a",
425
  interactive=True
426
  )
427
 
428
- max_waveforms_inputs = gr.Slider(minimum=1,
429
- maximum=100,
430
- value=10,
431
- label="Max waveforms per section",
432
- step=1,
433
- info="Maximum number of waveforms to show per section\n (to avoid long prediction times)",
434
- interactive=True,
435
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
 
437
  button = gr.Button("Predict phases")
438
- outputs_section = gr.Image(label='Waveforms with Phases Marked', type='numpy', interactive=False)
439
-
 
440
  button.click(predict_on_section,
441
  inputs=[client_inputs, timestamp_inputs,
442
  eq_lat_inputs, eq_lon_inputs,
443
  radius_inputs, source_depth_inputs,
444
  velocity_inputs, max_waveforms_inputs],
445
- outputs=outputs_section)
446
 
447
  demo.launch()
 
115
  return coeff
116
 
117
  def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source_depth_km, velocity_model, max_waveforms):
118
+ distances, t0s, st_lats, st_lons, waveforms, names = [], [], [], [], [], []
119
 
120
  taup_model = TauPyModel(model=velocity_model)
121
  client = Client(client_name)
 
197
  st_lats.append(station.latitude)
198
  st_lons.append(station.longitude)
199
  waveforms.append(waveform)
200
+ names.append(f"{network.code}.{station.code}")
201
 
202
  print(f"Added {network.code}.{station.code} to the list of waveforms")
203
 
 
227
  t0s = np.array(t0s)[selection_indexes]
228
  st_lats = np.array(st_lats)[selection_indexes]
229
  st_lons = np.array(st_lons)[selection_indexes]
230
+ names = np.array(names)[selection_indexes]
231
 
232
  waveforms = [torch.tensor(waveform) for waveform in waveforms]
233
 
 
266
  topo_map.da.plot(ax = ax[2], cmap='Greys', add_colorbar=False, add_labels=False)
267
  ax[1].imshow(hillshade, cmap="Greys", alpha=0.5)
268
 
269
+ output_picks = pd.DataFrame({'station_name' : [], 'starttime' : [],
270
+ 'p_phase' : [], 'p_uncertainty' : [], 's_phase' : [], 's_uncertainty' : [],
271
+ 'velocity_p' : [], 'velocity_s' : []})
272
+
273
+
274
  for i in range(len(waveforms)):
275
  print(f"Plotting waveform {i+1}/{len(waveforms)}")
276
  current_P = p_phases[i::len(waveforms)]
 
298
  velocity_s = (distances[i]*111.2)/(delta_t+current_S.mean()*60).item()
299
 
300
  print(f"Station {st_lats[i]}, {st_lons[i]} has P velocity {velocity_p} and S velocity {velocity_s}")
301
+
302
+ output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], 'starttime' : [str(t0s[i])],
303
+ 'p_phase' : [(delta_t+current_P.mean()*60).item()], 'p_uncertainty' : [current_P.std().item()*60],
304
+ 's_phase' : [(delta_t+current_S.mean()*60).item()], 's_uncertainty' : [current_S.std().item()*60],
305
+ 'velocity_p' : [velocity_p], 'velocity_s' : [velocity_s]}))
306
 
307
  # Generate an array from st_lat to eq_lat and from st_lon to eq_lon
308
  x = np.linspace(st_lons[i], eq_lon, 50)
 
331
  cbar.set_label('S Velocity (km/s)')
332
  ax[2].set_title('S Velocity')
333
 
 
 
334
  plt.subplots_adjust(hspace=0., wspace=0.5)
335
 
336
  fig.canvas.draw();
337
  image = np.array(fig.canvas.renderer.buffer_rgba())
338
  plt.close(fig)
339
 
340
+ return image, output_picks
341
 
342
 
343
  model = Onset_picker.load_from_checkpoint("./weights.ckpt",
 
384
  with gr.Tab("Select earthquake from catalogue"):
385
  gr.Markdown("""Select an earthquake from the global earthquake catalogue and the app will download the waveform from the FDSN client of your choice.
386
  """)
 
 
 
 
 
 
 
 
 
387
  with gr.Row():
388
+ client_inputs = gr.Dropdown(
389
+ choices = list(URL_MAPPINGS.keys()),
390
+ label="FDSN Client",
391
+ info="Select one of the available FDSN clients",
392
+ value = "IRIS",
393
+ interactive=True
394
+ )
395
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  velocity_inputs = gr.Dropdown(
397
  choices = ['1066a', '1066b', 'ak135',
398
+ 'ak135f', 'herrin', 'iasp91',
399
+ 'jb', 'prem', 'pwdk'],
400
  label="1D velocity model",
401
  info="Velocity model for station selection",
402
  value = "1066a",
403
  interactive=True
404
  )
405
 
406
+ with gr.Column(scale=4):
407
+ with gr.Row():
408
+ timestamp_inputs = gr.Textbox(value='2019-07-04 17:33:49',
409
+ placeholder='YYYY-MM-DD HH:MM:SS',
410
+ label="Timestamp",
411
+ info="Timestamp of the earthquake",
412
+ max_lines=1,
413
+ interactive=True)
414
+
415
+ eq_lat_inputs = gr.Number(value=35.766,
416
+ label="Latitude",
417
+ info="Latitude of the earthquake",
418
+ interactive=True)
419
+
420
+ eq_lon_inputs = gr.Number(value=-117.605,
421
+ label="Longitude",
422
+ info="Longitude of the earthquake",
423
+ interactive=True)
424
+
425
+ source_depth_inputs = gr.Number(value=10,
426
+ label="Source depth (km)",
427
+ info="Depth of the earthquake",
428
+ interactive=True)
429
+
430
+
431
+
432
+ with gr.Column(scale=2):
433
+ with gr.Row():
434
+ radius_inputs = gr.Slider(minimum=1,
435
+ maximum=150,
436
+ value=50, label="Radius (km)",
437
+ step=10,
438
+ info="""Select the radius around the earthquake to download data from.\n
439
+ Note that the larger the radius, the longer the app will take to run.""",
440
+ interactive=True)
441
+
442
+ max_waveforms_inputs = gr.Slider(minimum=1,
443
+ maximum=100,
444
+ value=10,
445
+ label="Max waveforms per section",
446
+ step=1,
447
+ info="Maximum number of waveforms to show per section\n (to avoid long prediction times)",
448
+ interactive=True,
449
+ )
450
 
451
  button = gr.Button("Predict phases")
452
+ output_image = gr.Image(label='Waveforms with Phases Marked', type='numpy', interactive=False)
453
+ output_picks = gr.Dataframe(label='# Pick data', type='pandas', interactive=False)
454
+
455
  button.click(predict_on_section,
456
  inputs=[client_inputs, timestamp_inputs,
457
  eq_lat_inputs, eq_lon_inputs,
458
  radius_inputs, source_depth_inputs,
459
  velocity_inputs, max_waveforms_inputs],
460
+ outputs=[output_image, output_picks])
461
 
462
  demo.launch()
data/cached/BK_MCCM_2023-04-01T16:43:30.541616Z.mseed ADDED
Binary file (78.3 kB). View file
 
data/cached/BK_SAO_2023-04-01T16:43:36.718558Z.mseed ADDED
Binary file (76.3 kB). View file
 
data/cached/NC_C006_2023-04-01T16:43:22.900707Z.mseed ADDED
Binary file (50.7 kB). View file
 
data/cached/NC_C031_2023-04-01T16:43:22.656861Z.mseed ADDED
Binary file (53.8 kB). View file
 
data/cached/NC_C050_2023-04-01T16:43:24.524689Z.mseed ADDED
Binary file (81.4 kB). View file
 
data/cached/NC_C055_2023-04-01T16:43:24.930990Z.mseed ADDED
Binary file (55.3 kB). View file
 
data/cached/NC_C056_2023-04-01T16:43:22.066458Z.mseed ADDED
Binary file (52.7 kB). View file
 
data/cached/NC_G004_2023-04-01T16:43:40.683359Z.mseed ADDED
Binary file (49.2 kB). View file
 
data/cached/NC_J010_2023-04-01T16:43:25.779606Z.mseed ADDED
Binary file (54.3 kB). View file
 
data/cached/NC_J068_2023-04-01T16:43:26.681315Z.mseed ADDED
Binary file (46.1 kB). View file
 
data/cached/NC_RWSVT_2023-04-01T16:43:23.543745Z.mseed ADDED
Binary file (48.6 kB). View file
 
data/cached/PB_B054_2023-04-01T16:43:22.147061Z.mseed ADDED
Binary file (53.2 kB). View file
 
data/cached/PB_B057_2023-04-01T16:43:26.668494Z.mseed ADDED
Binary file (51.7 kB). View file
 
data/cached/PB_B058_2023-04-01T16:43:35.559392Z.mseed ADDED
Binary file (38.9 kB). View file
 
data/cached/PB_B065_2023-04-01T16:43:36.828013Z.mseed ADDED
Binary file (5.12 kB). View file
 
data/cached/PB_B066_2023-04-01T16:43:34.748830Z.mseed ADDED
Binary file (35.3 kB). View file
 
data/cached/PB_B067_2023-04-01T16:43:36.084437Z.mseed ADDED
Binary file (32.3 kB). View file
 
data/cached/PB_P176_2023-04-01T16:43:25.099350Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P181_2023-04-01T16:43:23.984589Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P197_2023-04-01T16:43:32.497268Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P199_2023-04-01T16:43:28.886780Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P201_2023-04-01T16:43:33.477717Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P224_2023-04-01T16:43:22.286686Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P248_2023-04-01T16:43:24.960417Z.mseed ADDED
Binary file (13.8 kB). View file
 
data/cached/PB_P262_2023-04-01T16:43:24.445973Z.mseed ADDED
Binary file (13.8 kB). View file