Spaces:
Runtime error
Runtime error
File size: 163,423 Bytes
05d0cc5 f32279c 05d0cc5 f32279c 05d0cc5 f32279c 05d0cc5 f32279c 05d0cc5 15dbd99 05d0cc5 66ff4f5 05d0cc5 f5471b4 1ed8d1b 5734e39 05d0cc5 15dbd99 eeca930 05d0cc5 d59f437 f5471b4 639fbda 05d0cc5 f5471b4 a237ee5 639fbda f5471b4 a237ee5 639fbda bfda450 05d0cc5 bfda450 05d0cc5 50edc36 05d0cc5 bfda450 05d0cc5 639fbda 5734e39 639fbda 05d0cc5 bfda450 05d0cc5 bfda450 05d0cc5 bfda450 a237ee5 05d0cc5 9c68237 05d0cc5 5734e39 d59f437 d4f26e7 68d65f8 05d0cc5 5734e39 05d0cc5 5734e39 d4f26e7 5734e39 05d0cc5 d59f437 05d0cc5 5734e39 05d0cc5 5734e39 05d0cc5 5734e39 05d0cc5 5734e39 05d0cc5 5734e39 d4f26e7 d59f437 5734e39 d59f437 5734e39 d59f437 5734e39 eeca930 5734e39 05d0cc5 68d65f8 05d0cc5 5734e39 d4f26e7 5734e39 639fbda 5734e39 639fbda d4f26e7 5734e39 68d65f8 05d0cc5 5734e39 05d0cc5 d4f26e7 d59f437 5734e39 eeca930 5734e39 d4f26e7 9c68237 d4f26e7 15dbd99 5734e39 d4f26e7 15dbd99 d59f437 15dbd99 d4f26e7 15dbd99 d4f26e7 15dbd99 d4f26e7 5734e39 d4f26e7 5734e39 d4f26e7 5734e39 68d65f8 d4f26e7 9c68237 d59f437 5734e39 d59f437 eeca930 d59f437 5734e39 eeca930 5734e39 eeca930 5734e39 eeca930 5734e39 eeca930 5734e39 15dbd99 05d0cc5 66ff4f5 636d133 66ff4f5 a237ee5 1ed8d1b a237ee5 1ed8d1b 636d133 a237ee5 636d133 a237ee5 636d133 a237ee5 1ed8d1b a237ee5 1ed8d1b a237ee5 1ed8d1b a237ee5 1ed8d1b a237ee5 1ed8d1b a237ee5 e16c9d0 2598b7d e16c9d0 05d0cc5 50edc36 5af4ad6 636d133 1ed8d1b 636d133 1ed8d1b 636d133 1ed8d1b e16c9d0 636d133 639fbda 636d133 05d0cc5 82bf5ac d4f26e7 82bf5ac 9c68237 05d0cc5 eeca930 5734e39 eeca930 baf6507 eeca930 68d65f8 eeca930 d4f26e7 eeca930 d4f26e7 05d0cc5 68d65f8 a237ee5 1ed8d1b a237ee5 1ed8d1b f32279c a237ee5 05d0cc5 1ed8d1b a237ee5 e16c9d0 a237ee5 e16c9d0 1ed8d1b 05d0cc5 a237ee5 05d0cc5 636d133 05d0cc5 a237ee5 05d0cc5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Running on local URL: http://127.0.0.1:7861\n",
"\n",
"To create a public link, set `share=True` in `launch()`.\n"
]
},
{
"data": {
"text/html": [
"<div><iframe src=\"http://127.0.0.1:7861/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": []
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Gradio app that takes seismic waveform as input and marks 2 phases on the waveform as output.\n",
"\n",
"import gradio as gr\n",
"import numpy as np\n",
"import pandas as pd\n",
"from phasehunter.data_preparation import prepare_waveform\n",
"import torch\n",
"import io\n",
"\n",
"from scipy.stats import gaussian_kde\n",
"from scipy.signal import resample\n",
"from scipy.interpolate import interp1d\n",
"\n",
"from bmi_topography import Topography\n",
"import earthpy.spatial as es\n",
"\n",
"import obspy\n",
"from obspy.clients.fdsn import Client\n",
"from obspy.clients.fdsn.header import FDSNNoDataException, FDSNTimeoutException, FDSNInternalServerException\n",
"from obspy.geodetics.base import locations2degrees\n",
"from obspy.taup import TauPyModel\n",
"from obspy.taup.helper_classes import SlownessModelError\n",
"\n",
"from obspy.clients.fdsn.header import URL_MAPPINGS\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.dates as mdates\n",
"from mpl_toolkits.axes_grid1 import ImageGrid\n",
"\n",
"from glob import glob\n",
"\n",
"\n",
"def resample_waveform(waveform, original_freq, target_freq):\n",
" \"\"\"\n",
" Resample a waveform from original frequency to target frequency using SciPy's resample function.\n",
" \n",
" Args:\n",
" waveform (numpy.ndarray): The input waveform as a 1D array.\n",
" original_freq (float): The original sampling frequency of the waveform.\n",
" target_freq (float): The target sampling frequency of the waveform.\n",
" \n",
" Returns:\n",
" resampled_waveform (numpy.ndarray): The resampled waveform as a 1D array.\n",
" \"\"\"\n",
" # Calculate the resampling ratio\n",
" resampling_ratio = target_freq / original_freq\n",
" # Calculate the new length of the resampled waveform\n",
" resampled_length = int(waveform.shape[-1] * resampling_ratio)\n",
" # Resample the waveform using SciPy's resample function\n",
" resampled_waveform = resample(waveform, resampled_length, axis=-1)\n",
" \n",
" return resampled_waveform\n",
"\n",
"def sort_channels_to_ZNE(waveform, channels):\n",
" # Input:\n",
" # waveform: a 2D numpy array with shape (3, n), where n is the number of samples\n",
" # channels: a list or tuple of 3 strings representing the channel order, e.g. ('N', 'Z', 'E')\n",
" channels = list(channels)\n",
"\n",
" if len(channels) != 3 or set(channels) != {'Z', 'N', 'E'}:\n",
" raise ValueError(\"Invalid channel input. It should be a permutation of 'Z', 'N', and 'E'.\")\n",
"\n",
" # Find the indices of the Z, N, and E channels\n",
" z_index = channels.index('Z')\n",
" n_index = channels.index('N')\n",
" e_index = channels.index('E')\n",
" \n",
" print(z_index, n_index, e_index)\n",
" # Sort the channels to ZNE\n",
" sorted_waveform = waveform[[z_index, n_index, e_index], :]\n",
" \n",
" return sorted_waveform\n",
"\n",
"def make_prediction(waveform, sampling_rate, order):\n",
" waveform = np.load(waveform)\n",
" print('Loaded', waveform.shape)\n",
"\n",
" if len(waveform.shape) == 1:\n",
" waveform = waveform.reshape(1, waveform.shape[0])\n",
"\n",
" elif waveform.shape[0] == 3:\n",
" waveform = sort_channels_to_ZNE(waveform, order)\n",
"\n",
" if sampling_rate != 100:\n",
" waveform = resample_waveform(waveform, sampling_rate, 100)\n",
" print('Resampled', waveform.shape)\n",
"\n",
"\n",
" orig_waveform = waveform[:, :6000].copy()\n",
" processed_input = prepare_waveform(waveform)\n",
"\n",
" # Make prediction\n",
" with torch.inference_mode():\n",
" output = model(processed_input)\n",
"\n",
" p_phase = output[:, 0]\n",
" s_phase = output[:, 1]\n",
"\n",
" return processed_input, p_phase, s_phase, orig_waveform\n",
"\n",
"\n",
"def mark_phases(waveform, uploaded_file, p_thres, s_thres, sampling_rate, order):\n",
"\n",
" if uploaded_file is not None:\n",
" waveform = uploaded_file.name\n",
"\n",
" processed_input, p_phase, s_phase, orig_waveform = make_prediction(waveform, sampling_rate, order)\n",
"\n",
" # Create a plot of the waveform with the phases marked\n",
" if sum(processed_input[0][2] == 0): #if input is 1C\n",
" fig, ax = plt.subplots(nrows=2, figsize=(10, 2), sharex=True)\n",
"\n",
" ax[0].plot(orig_waveform[0], color='black', lw=1)\n",
" ax[0].set_ylabel('Norm. Ampl.')\n",
"\n",
" else: #if input is 3C\n",
" fig, ax = plt.subplots(nrows=4, figsize=(10, 6), sharex=True)\n",
" ax[0].plot(orig_waveform[0], color='black', lw=1)\n",
" ax[1].plot(orig_waveform[1], color='black', lw=1)\n",
" ax[2].plot(orig_waveform[2], color='black', lw=1)\n",
"\n",
" ax[0].set_ylabel('Z')\n",
" ax[1].set_ylabel('N')\n",
" ax[2].set_ylabel('E')\n",
"\n",
"\n",
" do_we_have_p = (p_phase.std().item()*60 < p_thres)\n",
" if do_we_have_p:\n",
" p_phase_plot = p_phase*processed_input.shape[-1]\n",
" p_kde = gaussian_kde(p_phase_plot)\n",
" p_dist_space = np.linspace( min(p_phase_plot)-10, max(p_phase_plot)+10, 500 )\n",
" ax[-1].plot( p_dist_space, p_kde(p_dist_space), color='r')\n",
" else:\n",
" ax[-1].text(0.5, 0.75, 'No P phase detected', horizontalalignment='center', verticalalignment='center', transform=ax[-1].transAxes)\n",
"\n",
" do_we_have_s = (s_phase.std().item()*60 < s_thres)\n",
" if do_we_have_s:\n",
" s_phase_plot = s_phase*processed_input.shape[-1]\n",
" s_kde = gaussian_kde(s_phase_plot)\n",
" s_dist_space = np.linspace( min(s_phase_plot)-10, max(s_phase_plot)+10, 500 )\n",
" ax[-1].plot( s_dist_space, s_kde(s_dist_space), color='b')\n",
"\n",
" for a in ax:\n",
" a.axvline(p_phase.mean()*processed_input.shape[-1], color='r', linestyle='--', label='P', alpha=do_we_have_p)\n",
" a.axvline(s_phase.mean()*processed_input.shape[-1], color='b', linestyle='--', label='S', alpha=do_we_have_s)\n",
" else:\n",
" ax[-1].text(0.5, 0.25, 'No S phase detected', horizontalalignment='center', verticalalignment='center', transform=ax[-1].transAxes)\n",
"\n",
" ax[-1].set_xlabel('Time, samples')\n",
" ax[-1].set_ylabel('Uncert., samples')\n",
" ax[-1].legend()\n",
"\n",
" plt.subplots_adjust(hspace=0., wspace=0.)\n",
"\n",
" # Convert the plot to an image and return it\n",
" fig.canvas.draw()\n",
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
" plt.close(fig)\n",
" return image\n",
"\n",
"def bin_distances(distances, bin_size=10):\n",
" # Bin the distances into groups of `bin_size` kilometers\n",
" binned_distances = {}\n",
" for i, distance in enumerate(distances):\n",
" bin_index = distance // bin_size\n",
" if bin_index not in binned_distances:\n",
" binned_distances[bin_index] = (distance, i)\n",
" elif i < binned_distances[bin_index][1]:\n",
" binned_distances[bin_index] = (distance, i)\n",
"\n",
" # Select the first distance in each bin and its index\n",
" first_distances = []\n",
" for bin_index in binned_distances:\n",
" first_distance, first_distance_index = binned_distances[bin_index]\n",
" first_distances.append(first_distance_index)\n",
" \n",
" return first_distances\n",
"\n",
"def variance_coefficient(residuals):\n",
" # calculate the variance of the residuals\n",
" var = residuals.var()\n",
" # scale the variance to a coefficient between 0 and 1\n",
" coeff = 1 - (var / (residuals.max() - residuals.min()))\n",
" return coeff\n",
"\n",
"def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source_depth_km, velocity_model, max_waveforms, conf_thres_P, conf_thres_S):\n",
" distances, t0s, st_lats, st_lons, waveforms, names = [], [], [], [], [], []\n",
" \n",
" taup_model = TauPyModel(model=velocity_model)\n",
" client = Client(client_name)\n",
"\n",
" window = radius_km / 111.2\n",
" max_waveforms = int(max_waveforms)\n",
"\n",
" assert eq_lat - window > -90 and eq_lat + window < 90, \"Latitude out of bounds\"\n",
" assert eq_lon - window > -180 and eq_lon + window < 180, \"Longitude out of bounds\"\n",
"\n",
" starttime = obspy.UTCDateTime(timestamp)\n",
" endtime = starttime + 120\n",
"\n",
" try:\n",
" print('Starting to download inventory')\n",
" inv = client.get_stations(network=\"*\", station=\"*\", location=\"*\", channel=\"*H*\", \n",
" starttime=starttime, endtime=endtime, \n",
" minlatitude=(eq_lat-window), maxlatitude=(eq_lat+window),\n",
" minlongitude=(eq_lon-window), maxlongitude=(eq_lon+window), \n",
" level='station')\n",
" print('Finished downloading inventory')\n",
" \n",
" except (IndexError, FDSNNoDataException, FDSNTimeoutException, FDSNInternalServerException):\n",
" fig, ax = plt.subplots()\n",
" ax.text(0.5,0.5,'Something is wrong with the data provider, try another')\n",
" fig.canvas.draw();\n",
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
" plt.close(fig)\n",
" return image\n",
" \n",
" waveforms = []\n",
" cached_waveforms = glob(\"data/cached/*.mseed\")\n",
"\n",
" for network in inv:\n",
" if network.code == 'SY':\n",
" continue\n",
" for station in network:\n",
" print(f\"Processing {network.code}.{station.code}...\")\n",
" distance = locations2degrees(eq_lat, eq_lon, station.latitude, station.longitude)\n",
"\n",
" arrivals = taup_model.get_travel_times(source_depth_in_km=source_depth_km, \n",
" distance_in_degree=distance, \n",
" phase_list=[\"P\", \"S\"])\n",
"\n",
" if len(arrivals) > 0:\n",
"\n",
" starttime = obspy.UTCDateTime(timestamp) + arrivals[0].time - 15\n",
" endtime = starttime + 60\n",
" try:\n",
" filename=f'{network.code}_{station.code}_{starttime}'\n",
" if f\"data/cached/{filename}.mseed\" not in cached_waveforms:\n",
" print(f'Downloading waveform for {filename}')\n",
" waveform = client.get_waveforms(network=network.code, station=station.code, location=\"*\", channel=\"*\", \n",
" starttime=starttime, endtime=endtime)\n",
" waveform.write(f\"data/cached/{network.code}_{station.code}_{starttime}.mseed\", format=\"MSEED\")\n",
" print('Finished downloading and caching waveform')\n",
" else:\n",
" print('Reading cached waveform')\n",
" waveform = obspy.read(f\"data/cached/{network.code}_{station.code}_{starttime}.mseed\")\n",
" \n",
"\n",
" except (IndexError, FDSNNoDataException, FDSNTimeoutException, FDSNInternalServerException):\n",
" print(f'Skipping {network.code}_{station.code}_{starttime}')\n",
" continue\n",
" \n",
" waveform = waveform.select(channel=\"H[BH][ZNE]\")\n",
" waveform = waveform.merge(fill_value=0)\n",
" waveform = waveform[:3].sort(keys=['channel'], reverse=True)\n",
"\n",
" len_check = [len(x.data) for x in waveform]\n",
" if len(set(len_check)) > 1:\n",
" continue\n",
"\n",
" if len(waveform) == 3:\n",
" try:\n",
" waveform = prepare_waveform(np.stack([x.data for x in waveform]))\n",
"\n",
" distances.append(distance)\n",
" t0s.append(starttime)\n",
" st_lats.append(station.latitude)\n",
" st_lons.append(station.longitude)\n",
" waveforms.append(waveform)\n",
" names.append(f\"{network.code}.{station.code}\")\n",
"\n",
" print(f\"Added {network.code}.{station.code} to the list of waveforms\")\n",
"\n",
" except:\n",
" continue\n",
" \n",
" \n",
" # If there are no waveforms, return an empty plot\n",
" if len(waveforms) == 0:\n",
" print('No waveforms found')\n",
" fig, ax = plt.subplots()\n",
" # prints \"No waveforms found\" on the plot aligned at center and vertically\n",
" ax.text(0.5,0.5,'No waveforms found', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)\n",
" fig.canvas.draw();\n",
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
" plt.close(fig)\n",
"\n",
" output_picks = pd.DataFrame()\n",
" output_picks.to_csv('data/picks.csv', index=False)\n",
" output_csv = 'data/picks.csv'\n",
" return image, output_picks, output_csv\n",
" \n",
"\n",
" first_distances = bin_distances(distances, bin_size=10/111.2)\n",
"\n",
" # Edge case when there are way too many waveforms to process\n",
" selection_indexes = np.random.choice(first_distances, \n",
" np.min([len(first_distances), max_waveforms]),\n",
" replace=False)\n",
"\n",
" waveforms = np.array(waveforms)[selection_indexes]\n",
" distances = np.array(distances)[selection_indexes]\n",
" t0s = np.array(t0s)[selection_indexes]\n",
" st_lats = np.array(st_lats)[selection_indexes]\n",
" st_lons = np.array(st_lons)[selection_indexes]\n",
" names = np.array(names)[selection_indexes]\n",
"\n",
" waveforms = [torch.tensor(waveform) for waveform in waveforms]\n",
"\n",
" print('Starting to run predictions')\n",
" with torch.no_grad():\n",
" waveforms_torch = torch.vstack(waveforms)\n",
" output = model(waveforms_torch)\n",
"\n",
" p_phases = output[:, 0]\n",
" s_phases = output[:, 1]\n",
"\n",
" p_phases = p_phases.reshape(len(waveforms),-1)\n",
" s_phases = s_phases.reshape(len(waveforms),-1)\n",
"\n",
" # Max confidence - min variance \n",
" p_max_confidence = p_phases.std(axis=-1).min()\n",
" s_max_confidence = s_phases.std(axis=-1).min()\n",
"\n",
" print(f\"Starting plotting {len(waveforms)} waveforms\")\n",
" fig, ax = plt.subplots(ncols=3, figsize=(10, 3))\n",
" \n",
" # Plot topography\n",
" print('Fetching topography')\n",
" params = Topography.DEFAULT.copy()\n",
" extra_window = 0.5\n",
" params[\"south\"] = np.min([st_lats.min(), eq_lat])-extra_window\n",
" params[\"north\"] = np.max([st_lats.max(), eq_lat])+extra_window\n",
" params[\"west\"] = np.min([st_lons.min(), eq_lon])-extra_window\n",
" params[\"east\"] = np.max([st_lons.max(), eq_lon])+extra_window\n",
"\n",
" topo_map = Topography(**params)\n",
" topo_map.fetch()\n",
" topo_map.load()\n",
"\n",
" print('Plotting topo')\n",
" hillshade = es.hillshade(topo_map.da[0], altitude=10)\n",
" \n",
" topo_map.da.plot(ax = ax[1], cmap='Greys', add_colorbar=False, add_labels=False)\n",
" topo_map.da.plot(ax = ax[2], cmap='Greys', add_colorbar=False, add_labels=False)\n",
" ax[1].imshow(hillshade, cmap=\"Greys\", alpha=0.5)\n",
"\n",
" output_picks = pd.DataFrame({'station_name' : [], \n",
" 'st_lat' : [], 'st_lon' : [],\n",
" 'starttime' : [], \n",
" 'p_phase, s' : [], 'p_uncertainty, s' : [], \n",
" 's_phase, s' : [], 's_uncertainty, s' : [],\n",
" 'velocity_p, km/s' : [], 'velocity_s, km/s' : []})\n",
" \n",
" for i in range(len(waveforms)):\n",
" print(f\"Plotting waveform {i+1}/{len(waveforms)}\")\n",
" current_P = p_phases[i]\n",
" current_S = s_phases[i]\n",
" \n",
" x = [t0s[i] + pd.Timedelta(seconds=k/100) for k in np.linspace(0,6000,6000)]\n",
" x = mdates.date2num(x)\n",
"\n",
" # Normalize confidence for the plot\n",
" p_conf = 1/(current_P.std()/p_max_confidence).item()\n",
" s_conf = 1/(current_S.std()/s_max_confidence).item()\n",
"\n",
" delta_t = t0s[i].timestamp - obspy.UTCDateTime(timestamp).timestamp\n",
"\n",
" ax[0].plot(x, waveforms[i][0, 0]*10+distances[i]*111.2, color='black', alpha=0.5, lw=1)\n",
"\n",
" if (current_P.std().item()*60 < conf_thres_P) or (current_S.std().item()*60 < conf_thres_S):\n",
" ax[0].scatter(x[int(current_P.mean()*waveforms[i][0].shape[-1])], waveforms[i][0, 0].mean()+distances[i]*111.2, color='r', alpha=p_conf, marker='|')\n",
" ax[0].scatter(x[int(current_S.mean()*waveforms[i][0].shape[-1])], waveforms[i][0, 0].mean()+distances[i]*111.2, color='b', alpha=s_conf, marker='|')\n",
" \n",
" velocity_p = (distances[i]*111.2)/(delta_t+current_P.mean()*60).item()\n",
" velocity_s = (distances[i]*111.2)/(delta_t+current_S.mean()*60).item()\n",
"\n",
" # Generate an array from st_lat to eq_lat and from st_lon to eq_lon\n",
" x = np.linspace(st_lons[i], eq_lon, 50)\n",
" y = np.linspace(st_lats[i], eq_lat, 50)\n",
" \n",
" # Plot the array\n",
" ax[1].scatter(x, y, c=np.zeros_like(x)+velocity_p, alpha=0.1, vmin=0, vmax=8)\n",
" ax[2].scatter(x, y, c=np.zeros_like(x)+velocity_s, alpha=0.1, vmin=0, vmax=8)\n",
"\n",
" else:\n",
" velocity_p = np.nan\n",
" velocity_s = np.nan\n",
" \n",
" ax[0].set_ylabel('Z')\n",
" print(f\"Station {st_lats[i]}, {st_lons[i]} has P velocity {velocity_p} and S velocity {velocity_s}\")\n",
"\n",
" output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]], \n",
" 'st_lat' : [st_lats[i]], 'st_lon' : [st_lons[i]],\n",
" 'starttime' : [str(t0s[i])], \n",
" 'p_phase, s' : [(delta_t+current_P.mean()*60).item()], 'p_uncertainty, s' : [current_P.std().item()*60], \n",
" 's_phase, s' : [(delta_t+current_S.mean()*60).item()], 's_uncertainty, s' : [current_S.std().item()*60],\n",
" 'velocity_p, km/s' : [velocity_p], 'velocity_s, km/s' : [velocity_s]}))\n",
" \n",
" \n",
" # Add legend\n",
" ax[0].scatter(None, None, color='r', marker='|', label='P')\n",
" ax[0].scatter(None, None, color='b', marker='|', label='S')\n",
" ax[0].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))\n",
" ax[0].xaxis.set_major_locator(mdates.SecondLocator(interval=20))\n",
" ax[0].legend()\n",
"\n",
" print('Plotting stations')\n",
" for i in range(1,3):\n",
" ax[i].scatter(st_lons, st_lats, color='b', label='Stations')\n",
" ax[i].scatter(eq_lon, eq_lat, color='r', marker='*', label='Earthquake')\n",
" ax[i].set_aspect('equal')\n",
" ax[i].set_xticklabels(ax[i].get_xticks(), rotation = 50)\n",
"\n",
" fig.subplots_adjust(bottom=0.1, top=0.9, left=0.1, right=0.8,\n",
" wspace=0.02, hspace=0.02)\n",
" \n",
" cb_ax = fig.add_axes([0.83, 0.1, 0.02, 0.8])\n",
" cbar = fig.colorbar(ax[2].scatter(None, None, c=velocity_p, alpha=0.5, vmin=0, vmax=8), cax=cb_ax)\n",
"\n",
" cbar.set_label('Velocity (km/s)')\n",
" ax[1].set_title('P Velocity')\n",
" ax[2].set_title('S Velocity')\n",
"\n",
" for a in ax:\n",
" a.tick_params(axis='both', which='major', labelsize=8)\n",
" \n",
" plt.subplots_adjust(hspace=0., wspace=0.5)\n",
" fig.canvas.draw();\n",
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
" plt.close(fig)\n",
"\n",
" output_csv = f'data/velocity/{eq_lat}_{eq_lon}_{source_depth_km}_{timestamp}_{len(waveforms)}.csv'\n",
" output_picks.to_csv(output_csv, index=False)\n",
" \n",
" return image, output_picks, output_csv\n",
"\n",
"import numpy as np\n",
"from matplotlib import colors, cm\n",
"from scipy.interpolate import griddata\n",
"\n",
"def interpolate_vel_model(velocity_model, initial_velocity, lat_values, lon_values, depth_values, n_lat, n_lon, n_depth):\n",
" # Create a mask for points with the initial velocity\n",
" initial_velocity_mask = (velocity_model == initial_velocity)\n",
"\n",
" # Find the indices of points with non-initial velocities\n",
" non_initial_velocity_indices = np.argwhere(~initial_velocity_mask)\n",
"\n",
" # Extract the coordinates and corresponding velocities of the known points\n",
" known_points = np.column_stack([lat_values[non_initial_velocity_indices[:, 0]],\n",
" lon_values[non_initial_velocity_indices[:, 1]],\n",
" depth_values[non_initial_velocity_indices[:, 2]]])\n",
" \n",
" # Find the maximum depth in the known_points\n",
" max_known_depth = np.max(known_points[:, 2])\n",
"\n",
" known_velocities = velocity_model[~initial_velocity_mask]\n",
"\n",
" # Create a grid of points for the entire volume\n",
" grid_points = np.array(np.meshgrid(lat_values, lon_values, depth_values, indexing='ij')).reshape(3, -1).T\n",
"\n",
" # Create a mask for grid points that are deeper than the maximum known depth\n",
" depth_mask = grid_points[:, 2] <= max_known_depth\n",
"\n",
" # Interpolate the velocities at the grid points\n",
" interpolated_velocities = griddata(known_points, known_velocities, grid_points[depth_mask], method='linear')\n",
"\n",
" # Fill nan values with the nearest known velocities\n",
" interpolated_velocities_filled = griddata(known_points, known_velocities, grid_points[depth_mask], method='nearest')\n",
" interpolated_velocities[np.isnan(interpolated_velocities)] = interpolated_velocities_filled[np.isnan(interpolated_velocities)]\n",
"\n",
" # Initialize an array with the same length as grid_points and fill it with nan values\n",
" interpolated_velocities_with_depth_limit = np.full(grid_points.shape[0], np.nan)\n",
"\n",
" # Update the array with the interpolated velocities for the masked grid points\n",
" interpolated_velocities_with_depth_limit[depth_mask] = interpolated_velocities\n",
"\n",
" # Reshape the interpolated velocities to match the shape of the velocity_model\n",
" interpolated_velocity_model = interpolated_velocities_with_depth_limit.reshape(n_lat, n_lon, n_depth)\n",
"\n",
" return interpolated_velocity_model\n",
"\n",
"\n",
"# Function to find the closest index for a given value in an array\n",
"def find_closest_index(array, value):\n",
" return np.argmin(np.abs(array - value))\n",
"\n",
"def compute_velocity_model(azimuth, elevation, interpolate, n_lat, n_lon, n_depth):\n",
" filename = list(output_csv.temp_files)[0]\n",
" \n",
" df = pd.read_csv(filename)\n",
" filename = filename.split('/')[-1]\n",
" \n",
" # Current EQ location\n",
" eq_lat = float(filename.split(\"_\")[0])\n",
" eq_lon = float(filename.split(\"_\")[1])\n",
" eq_depth = float(filename.split(\"_\")[2])\n",
"\n",
" # Define the region of interest (latitude, longitude, and depth ranges)\n",
" lat_range = (np.min([df.st_lat.min(), eq_lat]), np.max([df.st_lat.max(), eq_lat]))\n",
" lon_range = (np.min([df.st_lon.min(), eq_lon]), np.max([df.st_lon.max(), eq_lon]))\n",
" depth_range = (0, 50)\n",
"\n",
" # Define the number of nodes in each dimension\n",
" num_points = 100\n",
"\n",
" taup_model = TauPyModel(model='1066a')\n",
"\n",
" # Create the grid\n",
" lat_values = np.linspace(lat_range[0], lat_range[1], n_lat)\n",
" lon_values = np.linspace(lon_range[0], lon_range[1], n_lon)\n",
" depth_values = np.linspace(depth_range[0], depth_range[1], n_depth)\n",
"\n",
" # Initialize the velocity model with constant values\n",
" initial_velocity = 0 # km/s, this can be P-wave or S-wave velocity\n",
" velocity_model = np.full((n_lat, n_lon, n_depth), initial_velocity, dtype=float)\n",
"\n",
" # Loop through the stations and update the velocity model\n",
" for i in range(len(df)):\n",
" if ~np.isnan(df['velocity_p, km/s'].iloc[i]):\n",
"\n",
" ray_path = taup_model.get_ray_paths_geo(source_depth_in_km=eq_depth,\n",
" source_latitude_in_deg=eq_lat,\n",
" source_longitude_in_deg=eq_lon,\n",
" receiver_latitude_in_deg=df.st_lat.iloc[i],\n",
" receiver_longitude_in_deg=df.st_lon.iloc[i],\n",
" phase_list=['P', 'S'])\n",
"\n",
" # Create the interpolator objects for latitude, longitude, and depth\n",
" interp_latitude = interp1d(np.linspace(0, ray_path[0].path['lat'].max(), len(ray_path[0].path['lat'])), ray_path[0].path['lat'])\n",
" interp_longitude = interp1d(np.linspace(0, ray_path[0].path['lon'].max(), len(ray_path[0].path['lon'])), ray_path[0].path['lon'])\n",
" interp_depth = interp1d(np.linspace(0, ray_path[0].path['depth'].max(), len(ray_path[0].path['depth'])), ray_path[0].path['depth'])\n",
"\n",
" # Resample the ray path to N points\n",
" lat_values_interp = interp_latitude(np.linspace(0, ray_path[0].path['lat'].max(), num_points))\n",
" lon_values_interp = interp_longitude(np.linspace(0, ray_path[0].path['lon'].max(), num_points))\n",
" depth_values_interp = interp_depth(np.linspace(0, ray_path[0].path['depth'].max(), num_points))\n",
"\n",
" # Loop through the interpolated coordinates and update the grid cells with the average P-wave velocity\n",
" for lat, lon, depth in zip(lat_values_interp, lon_values_interp, depth_values_interp):\n",
" lat_index = find_closest_index(lat_values, lat)\n",
" lon_index = find_closest_index(lon_values, lon)\n",
" depth_index = find_closest_index(depth_values, depth)\n",
" \n",
" if velocity_model[lat_index, lon_index, depth_index] == initial_velocity:\n",
" velocity_model[lat_index, lon_index, depth_index] = df['velocity_p, km/s'].iloc[i]\n",
" else:\n",
" velocity_model[lat_index, lon_index, depth_index] = (velocity_model[lat_index, lon_index, depth_index] +\n",
" df['velocity_p, km/s'].iloc[i]) / 2\n",
"\n",
" # Create the figure and axis\n",
" fig = plt.figure(figsize=(8, 8))\n",
" ax = fig.add_subplot(111, projection='3d')\n",
"\n",
" # Set the plot limits\n",
" ax.set_xlim3d(lat_range[0], lat_range[1])\n",
" ax.set_ylim3d(lon_range[0], lon_range[1])\n",
" ax.set_zlim3d(depth_range[1], depth_range[0])\n",
"\n",
" ax.set_xlabel('Latitude')\n",
" ax.set_ylabel('Longitude')\n",
" ax.set_zlabel('Depth (km)')\n",
" ax.set_title('Velocity Model')\n",
" \n",
" # Create the meshgrid\n",
" x, y, z = np.meshgrid(\n",
" np.linspace(lat_range[0], lat_range[1], velocity_model.shape[0]+1),\n",
" np.linspace(lon_range[0], lon_range[1], velocity_model.shape[1]+1),\n",
" np.linspace(depth_range[0], depth_range[1], velocity_model.shape[2]+1),\n",
" indexing='ij'\n",
" )\n",
"\n",
" # Create the color array\n",
" norm = plt.Normalize(vmin=2, vmax=8)\n",
" colors_vel = plt.cm.plasma(norm(velocity_model)) \n",
" \n",
" # Plot the voxels\n",
" if interpolate:\n",
" interpolated_velocity_model = interpolate_vel_model(velocity_model, initial_velocity, lat_values, lon_values, depth_values, n_lat, n_lon, n_depth)\n",
" colors_interp = plt.cm.plasma(norm(interpolated_velocity_model))\n",
" ax.voxels(x, y, z, interpolated_velocity_model > 0, facecolors=colors_interp, alpha=0.5, edgecolor='k')\n",
" \n",
" ax.voxels(x, y, z, velocity_model > 0, facecolors=colors_vel, alpha=1, edgecolor='black')\n",
"\n",
" # Set the view angle\n",
" ax.view_init(elev=elevation, azim=azimuth)\n",
"\n",
" m = cm.ScalarMappable(cmap=plt.cm.plasma, norm=norm)\n",
" m.set_array([])\n",
" plt.colorbar(m)\n",
"\n",
" # Show the plot\n",
" fig.canvas.draw();\n",
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
" plt.close(fig)\n",
"\n",
" return image\n",
"\n",
"# model = torch.jit.load(\"model.pt\")\n",
"model = torch.jit.load(\"model.pt\")\n",
"\n",
"model.eval()\n",
"\n",
"with gr.Blocks() as demo:\n",
" gr.HTML(\"\"\"\n",
"<div style=\"padding: 20px; border-radius: 10px;\">\n",
" <h1 style=\"font-size: 30px; text-align: center; margin-bottom: 20px;\">PhaseHunter <span style=\"animation: arrow-anim 10s linear infinite; display: inline-block; transform: rotate(45deg) translateX(-20px);\">🏹</span>\n",
"\n",
"<style>\n",
" @keyframes arrow-anim {\n",
" 0% { transform: translateX(-20px); }\n",
" 50% { transform: translateX(20px); }\n",
" 100% { transform: translateX(-20px); }\n",
" }\n",
"</style></h1> \n",
" \n",
" <p style=\"font-size: 16px; margin-bottom: 20px;\">Detect <span style=\"background-image: linear-gradient(to right, #ED213A, #93291E); \n",
" -webkit-background-clip: text;\n",
" -webkit-text-fill-color: transparent;\n",
" background-clip: text;\">P</span> and <span style=\"background-image: linear-gradient(to right, #00B4DB, #0083B0); \n",
" -webkit-background-clip: text;\n",
" -webkit-text-fill-color: transparent;\n",
" background-clip: text;\">S</span> seismic phases with <span style=\"background-image: linear-gradient(to right, #f12711, #f5af19); \n",
" -webkit-background-clip: text;\n",
" -webkit-text-fill-color: transparent;\n",
" background-clip: text;\">uncertainty</span></p>\n",
" <ul style=\"font-size: 16px; margin-bottom: 40px;\">\n",
" <li>Detect seismic phases by selecting a sample waveform or uploading your own waveform in <code>.npy</code> format.</li>\n",
" <li>Select an earthquake from the global earthquake catalogue and PhaseHunter will analyze seismic stations in the given radius.</li>\n",
" <li>Waveforms should be sampled at 100 samples/sec and have 3 (Z, N, E) or 1 (Z) channels. PhaseHunter analyzes the first 6000 samples of your file.</li>\n",
" </ul>\n",
"</div>\n",
"\"\"\")\n",
" with gr.Tab(\"Try on a single station\"):\n",
" with gr.Row(): \n",
" # Define the input and output types for Gradio\n",
" inputs = gr.Dropdown(\n",
" [\"data/sample/sample_0.npy\", \n",
" \"data/sample/sample_1.npy\", \n",
" \"data/sample/sample_2.npy\"], \n",
" label=\"Sample waveform\", \n",
" info=\"Select one of the samples\",\n",
" value = \"data/sample/sample_0.npy\"\n",
" )\n",
" with gr.Column(scale=1):\n",
" P_thres_inputs = gr.Slider(minimum=0.01,\n",
" maximum=1,\n",
" value=0.1,\n",
" label=\"P uncertainty threshold (s)\",\n",
" step=0.01,\n",
" info=\"Acceptable uncertainty for P picks expressed in std() seconds\",\n",
" interactive=True,\n",
" )\n",
" \n",
" S_thres_inputs = gr.Slider(minimum=0.01,\n",
" maximum=1,\n",
" value=0.2,\n",
" label=\"S uncertainty threshold (s)\",\n",
" step=0.01,\n",
" info=\"Acceptable uncertainty for S picks expressed in std() seconds\",\n",
" interactive=True,\n",
" )\n",
" with gr.Column(scale=1):\n",
" upload = gr.File(label=\"Upload your waveform\")\n",
" with gr.Row():\n",
" sampling_rate_inputs = gr.Slider(minimum=10,\n",
" maximum=1000,\n",
" value=100,\n",
" label=\"Samlping rate, Hz\",\n",
" step=10,\n",
" info=\"Sampling rate of the waveform\",\n",
" interactive=True,\n",
" )\n",
" order_input = gr.Text(value='ZNE', \n",
" label='Channel order', \n",
" info='Order of the channels in the waveform file (e.g. ZNE)')\n",
"\n",
" button = gr.Button(\"Predict phases\")\n",
" outputs = gr.Image(label='Waveform with Phases Marked', type='numpy', interactive=False)\n",
" \n",
" button.click(mark_phases, inputs=[inputs, upload, \n",
" P_thres_inputs, S_thres_inputs,\n",
" sampling_rate_inputs, order_input], \n",
" outputs=outputs) \n",
" with gr.Tab(\"Select earthquake from catalogue\"):\n",
"\n",
" gr.HTML(\"\"\"\n",
" <div style=\"padding: 20px; border-radius: 10px; font-size: 16px;\">\n",
" <p style=\"font-weight: bold; font-size: 24px; margin-bottom: 20px;\">Using PhaseHunter to Analyze Seismic Waveforms</p>\n",
" <p>Select an earthquake from the global earthquake catalogue (e.g. <a href=\"https://earthquake.usgs.gov/earthquakes/map\">USGS</a>) and the app will download the waveform from the FDSN client of your choice. The app will use a velocity model of your choice to select appropriate time windows for each station within a specified radius of the earthquake.</p>\n",
" <p>The app will then analyze the waveforms and mark the detected phases on the waveform. Pick data for each waveform is reported in seconds from the start of the waveform.</p>\n",
" <p>Velocities are derived from distance and travel time determined by PhaseHunter picks (<span style=\"font-style: italic;\">v = distance/predicted_pick_time</span>). The background of the velocity plot is colored by DEM.</p>\n",
" </div>\n",
" \"\"\")\n",
" with gr.Row(): \n",
" with gr.Column(scale=2):\n",
" client_inputs = gr.Dropdown(\n",
" choices = list(URL_MAPPINGS.keys()), \n",
" label=\"FDSN Client\", \n",
" info=\"Select one of the available FDSN clients\",\n",
" value = \"IRIS\",\n",
" interactive=True\n",
" )\n",
"\n",
" velocity_inputs = gr.Dropdown(\n",
" choices = ['1066a', '1066b', 'ak135', \n",
" 'ak135f', 'herrin', 'iasp91', \n",
" 'jb', 'prem', 'pwdk'], \n",
" label=\"1D velocity model\", \n",
" info=\"Velocity model for station selection\",\n",
" value = \"1066a\",\n",
" interactive=True\n",
" )\n",
"\n",
" with gr.Column(scale=2):\n",
" timestamp_inputs = gr.Textbox(value='2019-07-04T17:33:49-00',\n",
" placeholder='YYYY-MM-DDTHH:MM:SS-TZ',\n",
" label=\"Timestamp\",\n",
" info=\"Timestamp of the earthquake\",\n",
" max_lines=1,\n",
" interactive=True)\n",
" \n",
" source_depth_inputs = gr.Number(value=10,\n",
" label=\"Source depth (km)\",\n",
" info=\"Depth of the earthquake\",\n",
" interactive=True)\n",
" \n",
" with gr.Column(scale=2):\n",
" eq_lat_inputs = gr.Number(value=35.766, \n",
" label=\"Latitude\", \n",
" info=\"Latitude of the earthquake\",\n",
" interactive=True)\n",
" \n",
" eq_lon_inputs = gr.Number(value=-117.605,\n",
" label=\"Longitude\",\n",
" info=\"Longitude of the earthquake\",\n",
" interactive=True)\n",
" \n",
" with gr.Column(scale=2):\n",
" radius_inputs = gr.Slider(minimum=1, \n",
" maximum=200, \n",
" value=50, \n",
" label=\"Radius (km)\", \n",
" step=10,\n",
" info=\"\"\"Select the radius around the earthquake to download data from.\\n \n",
" Note that the larger the radius, the longer the app will take to run.\"\"\",\n",
" interactive=True)\n",
" \n",
" max_waveforms_inputs = gr.Slider(minimum=1,\n",
" maximum=100,\n",
" value=10,\n",
" label=\"Max waveforms per section\",\n",
" step=1,\n",
" info=\"Maximum number of waveforms to show per section\\n (to avoid long prediction times)\",\n",
" interactive=True,\n",
" )\n",
" with gr.Column(scale=2):\n",
" P_thres_inputs = gr.Slider(minimum=0.01,\n",
" maximum=1,\n",
" value=0.1,\n",
" label=\"P uncertainty threshold, s\",\n",
" step=0.01,\n",
" info=\"Acceptable uncertainty for P picks expressed in std() seconds\",\n",
" interactive=True,\n",
" )\n",
" S_thres_inputs = gr.Slider(minimum=0.01,\n",
" maximum=1,\n",
" value=0.2,\n",
" label=\"S uncertainty threshold, s\",\n",
" step=0.01,\n",
" info=\"Acceptable uncertainty for S picks expressed in std() seconds\",\n",
" interactive=True,\n",
" )\n",
" \n",
" button = gr.Button(\"Predict phases\")\n",
" output_image = gr.Image(label='Waveforms with Phases Marked', type='numpy', interactive=False)\n",
" \n",
" with gr.Row():\n",
" with gr.Column(scale=2):\n",
" azimuth_input = gr.Slider(minimum=-180, maximum=180, value=0, step=5, label=\"Azimuth\", interactive=True)\n",
" elevation_input = gr.Slider(minimum=-90, maximum=90, value=30, step=5, label=\"Elevation\", interactive=True)\n",
"\n",
" with gr.Row():\n",
" interpolate_input = gr.Checkbox(label=\"Interpolate\", info=\"Interpolate velocity model\")\n",
" n_lat_input = gr.Slider(minimum=5, maximum=100, value=50, step=5, label=\"N lat\", info='Number of Lat grid points', interactive=True)\n",
" n_lon_input = gr.Slider(minimum=5, maximum=100, value=50, step=5, label=\"N lon\", info='Number of Lon grid points', interactive=True)\n",
" n_depth_input = gr.Slider(minimum=5, maximum=100, value=50, step=5, label=\"N depth\", info='Number of Depth grid points', interactive=True)\n",
" \n",
" button = gr.Button(\"Look at 3D Velocities\")\n",
" outputs_vel_model = gr.Image(label=\"3D Velocity Model\")\n",
"\n",
" button.click(compute_velocity_model, \n",
" inputs=[azimuth_input, elevation_input, \n",
" interpolate_input, n_lat_input, \n",
" n_lon_input, n_depth_input], \n",
" outputs=[outputs_vel_model])\n",
" \n",
" with gr.Row():\n",
" output_picks = gr.Dataframe(label='Pick data', \n",
" type='pandas', \n",
" interactive=False)\n",
" output_csv = gr.File(label=\"Output File\", file_types=[\".csv\"])\n",
"\n",
" button.click(predict_on_section, \n",
" inputs=[client_inputs, timestamp_inputs, \n",
" eq_lat_inputs, eq_lon_inputs, \n",
" radius_inputs, source_depth_inputs, \n",
" velocity_inputs, max_waveforms_inputs,\n",
" P_thres_inputs, S_thres_inputs],\n",
" outputs=[output_image, output_picks, output_csv])\n",
"\n",
"demo.launch()"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['__class__',\n",
" '__delattr__',\n",
" '__dict__',\n",
" '__dir__',\n",
" '__doc__',\n",
" '__eq__',\n",
" '__format__',\n",
" '__ge__',\n",
" '__getattribute__',\n",
" '__getstate__',\n",
" '__gt__',\n",
" '__hash__',\n",
" '__init__',\n",
" '__init_subclass__',\n",
" '__le__',\n",
" '__lt__',\n",
" '__module__',\n",
" '__ne__',\n",
" '__new__',\n",
" '__reduce__',\n",
" '__reduce_ex__',\n",
" '__repr__',\n",
" '__setattr__',\n",
" '__sizeof__',\n",
" '__str__',\n",
" '__subclasshook__',\n",
" '__weakref__',\n",
" 'azimuth',\n",
" 'distance',\n",
" 'incident_angle',\n",
" 'name',\n",
" 'path',\n",
" 'phase',\n",
" 'pierce',\n",
" 'purist_dist',\n",
" 'purist_distance',\n",
" 'purist_name',\n",
" 'ray_param',\n",
" 'ray_param_index',\n",
" 'ray_param_sec_degree',\n",
" 'receiver_depth',\n",
" 'source_depth',\n",
" 'takeoff_angle',\n",
" 'time']"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dir(ray_path[0])"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x1934d3710>"
]
},
"execution_count": 107,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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OBX5pWRMCdgENre37a0/ERGR4UOBlBwjKfCawZS0m0tljNv2FmBrfhMRERlGihZI3X777cydO5dIJEJlZWWnZa699lpmzZpFMBikpqamw/FVq1ZhjOmwlZSUHPH669evZ+bMmYRCIcaNG8c111xTOPb0009z0UUXUV1dTUlJCTU1NWzYsKHD+R++biik/Eldsikg18XSMgbwY714vzdLRESkmIo2RyqdTrNo0SLmzJnD2rVruyy3bNkynn/+eV555ZUOx2666SauvvrqdvvOOeccTj/99G6vfdddd3HnnXdyxx13MHv2bFpaWnj77bcLx5977jlmzpzJP/7jPzJ+/HgeeeQRrrzySioqKrjwwgsL5crLy9m+fXvhcz4gkM5ZCnOiOmNMWxkREZHho2iB1G233Qbke3a6cs899wCwd+/eTgOp0tJSSktLC5+3bt3K66+/zr333ttlnQcPHuQb3/gGDz/8MOecc05h/8yZMwv//+abb253znXXXccTTzzBL37xi3aBlDGGCRMmdHktOVz+PyVrbecBp82CU9pxv4iIyBA2pOZIrVmzhmnTpjFv3rwuyzz55JN4nse7777LKaecwsSJE7n00kvZtWtXt3VHo1FGjx7dbl88HmfKlClMmjSJiy66iNdee+2IbUylUsRisXbbiGDC+aVjbEuHQ9amAAfjHHlIVkREZCgZMoFUMplkw4YNLF++vNtyb731Fp7n8e1vf5u7776bn/3sZxw4cIDzzjuPdDrd6TkbN27kv//7v/nyl79c2HfyySezbt06fvnLX/KjH/0Iz/OYO3cu77zzTrfXX716NRUVFYVt0qRJvb/ZIcgYF+OMAVysF8PaBNamsF5zPqmnMwpjwgPdTBERkWOqV4HUihUrOp38ffi2bdu2ojR006ZNNDc3s2TJkm7LeZ5HJpPhnnvuYcGCBZx55pn85Cc/YceOHdTW1nYoX1tby5e//GX+8z//k1NPPbWwf86cOVx55ZXU1NQwf/58fvGLX1BVVcX3v//9bq+/cuVKotFoYTtST9hwYpwIxncctAVUADjlGLcaxx01oG0TEREphl7NkbrxxhtZunRpt2WmTp16NO3p0po1a7jwwgsZP358t+Wqq6sBmDFjRmFfVVUVY8eOpaGhoV3ZZ555hs997nP867/+K1deeWW39fr9fk477TR27tzZbblgMEgw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IiLSI67j8LUvfZozak4A8oHT4UrCQc4546P4HUMykcFa8HLgeBA70Mqrf2zgla0NxJqGz1t9yiNVZMojJSIiw43nWZ74f2/ws0de5L09UYIBH9NOqOKkSWMJuQYwZHIWP4ZMNkckEsDL5XBsPvI67rhKpp0ykXETKnCcwTnUN+B5pG6//Xbmzp1LJBKhsrKy0zLXXnsts2bNIhgMUlNT0+H4qlWrMMZ02EpKSrq99n//939zzjnnUFlZyahRo1iwYAFbt25tV+aVV15h3rx5hEIhJk2axD//8z93qOfBBx9k+vTphEIhPv7xj/PYY4/1+P5FRESGK8cxXDB/Bv/+T3/N3au+yJc/P5tPTDuOkrAfx+cjk7EEfC5ZL4fP55BszeDl8rmmjDG8s+sALz//Jm9ubxzyQ31FC6TS6TSLFi3ia1/7Wrflli1bxuLFizs9dtNNN7F79+5224wZM1i0aFGX9cXjcS644AImT57M888/z29/+1vKyspYsGABmUx+clwsFuP8889nypQpvPjii9xxxx2sWrWKH/zgB4V6nnvuOS677DKWL1/Oyy+/zMUXX8zFF1/Mq6++2oefhoiIyPATDPo56YTxzP7LqUyorsTzDMZAKOgnl83hug5gsXgYLMlEGmstjmOIxhK8uOVPPPeb19j3fnSgb6XPij60t379eq6//nqampq6LLNq1Soeeugh6urquq1r69at1NTU8OyzzzJv3rxOy7zwwgucfvrpNDQ0MGnSJAD++Mc/MnPmTHbs2MFJJ53E9773PW655RYaGxsJBAIArFixgoceeoht27YBsHjxYlpaWnjkkUcKdZ955pnU1NRw77339vj+NbQnIiIjQaw5wc439/DWm++TTmZwMFg8kon8IsfZdBbXdbA5S9O+GFt//xbv1u8DwO93mb9wJsuuP5/RVYPju3LAh/aKYc2aNUybNq3LIArg5JNPZsyYMaxdu5Z0Ok0ikWDt2rWccsopnHDCCQBs2bKFT3/604UgCmDBggVs376dgwcPFsqce+657epesGABW7Zs6baNqVSKWCzWbhMRERnuysvCnHrKRE47bTLlFRFy1mJwCAX9eDmLz/WBB+/9eT+/euC/ee/tfYVzM5kcTz1cxzWX/juN7x4YwLvovSETSCWTSTZs2MDy5cu7LVdWVsbTTz/Nj370I8LhMKWlpTz++OP8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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from scipy.interpolate import interp1d\n",
"\n",
"taup_model = TauPyModel(model='1066a')\n",
"\n",
"ray_path = taup_model.get_ray_paths_geo(source_depth_in_km=10,\n",
" source_latitude_in_deg=35.766,\n",
" source_longitude_in_deg=-117.605,\n",
" receiver_latitude_in_deg=35.98249,\n",
" receiver_longitude_in_deg=-117.80885,\n",
" phase_list=['P', 'S'])\n",
"\n",
"ray_path[0].path\n",
"\n",
"# Define the number of points N\n",
"N = 100\n",
"\n",
"# Create the interpolator objects for latitude, longitude, and depth\n",
"interp_latitude = interp1d(np.linspace(0, ray_path[0].path['lat'].max(), len(ray_path[0].path['lat'])), ray_path[0].path['lat'])\n",
"interp_longitude = interp1d(np.linspace(0, ray_path[0].path['lon'].max(), len(ray_path[0].path['lon'])), ray_path[0].path['lon'])\n",
"interp_depth = interp1d(np.linspace(0, ray_path[0].path['depth'].max(), len(ray_path[0].path['depth'])), ray_path[0].path['depth'])\n",
"\n",
"# Resample the ray path to N points\n",
"resampled_latitude = interp_latitude(np.linspace(0, ray_path[0].path['lat'].max(), N))\n",
"resampled_longitude = interp_longitude(np.linspace(0, ray_path[0].path['lon'].max(), N))\n",
"resampled_depth = interp_depth(np.linspace(0, ray_path[0].path['depth'].max(), N))\n",
"\n",
"plt.scatter(resampled_latitude, resampled_longitude, c=resampled_depth, cmap='viridis', alpha=0.1)\n",
"plt.scatter(ray_path[0].path['lat'], ray_path[0].path['lon'], c=ray_path[0].path['depth'], cmap='viridis')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([(825.43624587, 0. , 0. , 10. , 35.766 , -117.605 ),\n",
" (825.43624587, 0.26845098, 0.00012109, 11. , 35.7715199 , -117.61017979),\n",
" (825.43624587, 1.63173458, 0.00177268, 11.01091139, 35.84678737, -117.68090241),\n",
" (825.43624587, 2.99501819, 0.00342427, 11. , 35.92201332, -117.75175935),\n",
" (825.43624587, 3.26346917, 0.00354535, 10. , 35.92752691, -117.75695956),\n",
" (825.43624587, 4.33607208, 0.00402859, 6.00385879, 35.94952856, -117.77772004),\n",
" (825.43624587, 4.47129397, 0.00408945, 5.5 , 35.9522991 , -117.78033535),\n",
" (825.43624587, 5.20940225, 0.00442139, 2.74941477, 35.96740958, -117.79460335),\n",
" (825.43624587, 5.57829224, 0.00458712, 1.37456112, 35.97495353, -117.80172933),\n",
" (825.43624587, 5.94707298, 0.0047527 , 0. , 35.98248996, -117.80884997)],\n",
" dtype=[('p', '<f8'), ('time', '<f8'), ('dist', '<f8'), ('depth', '<f8'), ('lat', '<f8'), ('lon', '<f8')])"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ray_path[0].path"
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAnwAAAKSCAYAAABIowakAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAADSDUlEQVR4nOzdeZwcVb03/k9Vdfes3dOTdRKzEkJCIAkYIIRNlgAGRJY8V5EoQYGAgArcBzX+QLwoouhFuFwE9AHECwEFCeAViIAwyBIMgRDWkISErDNZJrNPb1Xn90fPqaleprumZyZ9pvrzfr0wZqbTc9Lp7vr095zzPZoQQoCIiIiIPEsv9gCIiIiIaHAx8BERERF5HAMfERERkccx8BERERF5HAMfERERkccx8BERERF5HAMfERERkccx8BERERF5HAMfERERkccx8BHRoNE0DT/5yU8G5b43b94MTdPwhz/8YVDuXwU/+clPoGlaQX/2oosuwqRJkwZ2QEQ0ZDHwERG+/OUvo7KyEm1tbb3eZtGiRQgEAti7d+9+HFnfPPPMM4MSMCdNmgRN0zB//vys3//9738PTdOgaRreeuutAf/5RET9xcBHRFi0aBG6urqwfPnyrN/v7OzEU089hS9+8YsYPnz4fh5ddhMnTkRXVxe+8Y1v2F975pln8B//8R+D8vPKy8vx0ksvoaGhIeN7Dz/8MMrLywfl5xIRDQQGPiLCl7/8ZQSDQSxbtizr95966il0dHRg0aJF+3lkvdM0DeXl5TAMY7/8vGOPPRbV1dX405/+lPL1bdu24Z///CfOPPPM/TIOIqJCMPARESoqKnDeeefhxRdfxK5duzK+v2zZMgSDQXz5y18GADQ3N+Pqq6/G+PHjUVZWhgMPPBC//OUvYVlW3p/1zjvvYMGCBQiFQqiursYpp5yClStXZtyuubkZ11xzDSZNmoSysjKMGzcOF154Ifbs2QMgcw3fRRddhLvuugsA7OlVTdMghMCkSZNw9tlnZ/yMSCSCmpoaXHbZZXnHXV5ejvPOOy8jFD/yyCOora3F6aefnvXP/eMf/8Dxxx+PqqoqhMNhnH322fjoo48ybvfqq6/iyCOPRHl5OaZMmYJ7772317E89NBDmDNnDioqKjBs2DCcf/752Lp1a96/AxGVLl+xB0BEali0aBEefPBB/PnPf8ZVV11lf72pqQkrVqzA1772NVRUVKCzsxNf+MIXsH37dlx22WWYMGECXn/9dSxduhQ7d+7E7bff3uvP+OCDD3D88ccjFArh+9//Pvx+P+69916ceOKJqK+vx9y5cwEA7e3tOP744/HRRx/hW9/6Fj7/+c9jz549ePrpp7Ft2zaMGDEi474vu+wy7NixA88//zz+53/+x/66pmn4+te/jltvvRVNTU0YNmyY/b2//vWvaG1txde//nVXj9EFF1yA0047DRs3bsSUKVMAJMPw//k//wd+vz/j9i+88AIWLFiAAw44AD/5yU/Q1dWFO++8E8ceeyzefvtte1PFe++9h9NOOw0jR47ET37yEyQSCdx4440YPXp0xn3efPPNuOGGG/CVr3wFl1xyCXbv3o0777wTJ5xwAt555x2Ew2FXfxciKjGCiEgIkUgkxJgxY8S8efNSvn7PPfcIAGLFihVCCCF++tOfiqqqKvHJJ5+k3O6HP/yhMAxDbNmyxf4aAHHjjTfavz/nnHNEIBAQGzdutL+2Y8cOEQwGxQknnGB/7cc//rEAIJ544omMcVqWJYQQYtOmTQKAeOCBB+zvXXnllSLb29q6desEAHH33XenfP3LX/6ymDRpkn2fvZk4caI488wzRSKREHV1deKnP/2pEEKIDz/8UAAQ9fX14oEHHhAAxKpVq+w/d9hhh4lRo0aJvXv32l979913ha7r4sILL0x5XMrLy8Vnn31mf+3DDz8UhmGk/H02b94sDMMQN998c8r43nvvPeHz+VK+vnjxYjFx4sScfy8iKh2c0iUiAIBhGDj//PPxxhtvYPPmzfbXly1bhtGjR+OUU04BADz22GM4/vjjUVtbiz179tj/zZ8/H6Zp4pVXXsl6/6Zp4u9//zvOOeccHHDAAfbXx4wZgwsuuACvvvoqWltbAQB/+ctfMHv2bJx77rkZ91NIm5KDDjoIc+fOxcMPP2x/rampCc8++ywWLVrk+j4Nw8BXvvIVPPLIIwCSmzXGjx+P448/PuO2O3fuxJo1a3DRRRelVBVnzZqFU089Fc888wyA5OOyYsUKnHPOOZgwYYJ9u4MPPjhjmviJJ56AZVn4yle+kvLY19XVYerUqXjppZfcPyhEVFIY+IjIJjdlyHVqckPC+eefb2+OWL9+PZ577jmMHDky5T/ZsiTbGkAA2L17Nzo7OzFt2rSM7x188MGwLMteh7Zx40YceuihA/p3u/DCC/Haa6/hs88+A5AMrvF4PGWXrxsXXHABPvzwQ7z77rtYtmwZzj///KyBUf6c3v6+e/bsQUdHB3bv3o2uri5MnTo143bpf3b9+vUQQmDq1KkZj/9HH33U62NPRMQ1fERkmzNnDqZPn45HHnkEP/rRj/DII49ACJGyO9eyLJx66qn4/ve/n/U+DjrooP013D45//zzcc011+Dhhx/Gj370Izz00EM44ogjsgayXObOnYspU6bg6quvxqZNm3DBBRcM0ogzWZYFTdPw7LPPZt2dXF1dvd/GQkRDCwMfEaVYtGgRbrjhBqxduxbLli3D1KlTceSRR9rfnzJlCtrb23ttQtybkSNHorKyEuvWrcv43scffwxd1zF+/Hj7Z7z//vt9Hnuuqdlhw4bhzDPPxMMPP4xFixbhtddey7nBJJevfe1r+NnPfoaDDz4Yhx12WNbbTJw4EQB6/fuOGDECVVVVKC8vR0VFBdavX59xu/Q/O2XKFAghMHnyZGWDNRGpiVO6RJRCVvN+/OMfY82aNRm9977yla/gjTfewIoVKzL+bHNzMxKJRNb7NQwDp512Gp566qmUNYKNjY1YtmwZjjvuOIRCIQDAwoUL8e6772ZtBC2E6HXsVVVV9jiy+cY3voEPP/wQ1113nb1msRCXXHIJbrzxRvznf/5nr7cZM2YMDjvsMDz44IMp43n//ffx97//HWeccQaA5ONy+umn48knn8SWLVvs23300UcZj/F5550HwzDwH//xHxmPgxBC6VNQiKi4WOEjohSTJ0/GMcccg6eeegoAMgLfddddh6effhpf+tKXcNFFF2HOnDno6OjAe++9h8cffxybN2/O2jYFAH72s5/h+eefx3HHHYcrrrgCPp8P9957L6LRKG699daUn/H444/j3/7t3/Ctb30Lc+bMQVNTE55++mncc889mD17dtb7nzNnDgDgu9/9Lk4//fSMUHfmmWdi+PDheOyxx7BgwQKMGjWqoMdo4sSJro5w+9WvfoUFCxZg3rx5uPjii+22LDU1NSl//j/+4z/w3HPP4fjjj8cVV1yBRCKBO++8E4cccgjWrl1r327KlCn42c9+hqVLl2Lz5s0455xzEAwGsWnTJixfvhxLlizB//2//7egvxMReVwxtwgTkZruuusuAUAcddRRWb/f1tYmli5dKg488EARCATEiBEjxDHHHCN+/etfi1gsZt8OaW1ZhBDi7bffFqeffrqorq4WlZWV4qSTThKvv/56xs/Yu3evuOqqq8TnPvc5EQgExLhx48TixYvFnj17hBDZ27IkEgnxne98R4wcOVJompa1RcsVV1whAIhly5a5fjxkW5ZcsrVlEUKIF154QRx77LGioqJChEIhcdZZZ4kPP/ww48/X19eLOXPmiEAgIA444ABxzz33iBtvvDHr3+Evf/mLOO6440RVVZWoqqoS06dPF1deeaVYt26dfRu2ZSEiJ02IHPMjREQec8011+C+++5DQ0MDKisriz0cIqL9gmv4iKhkRCIRPPTQQ1i4cCHDHhGVFK7hIyLP27VrF1544QU8/vjj2Lt3L773ve8Ve0hERPsVAx8Red6HH36IRYsWYdSoUfiv//qvXlupEBF5FdfwEREREXkc1/AREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHHMfAREREReRwDHxEREZHH+Yo9AFKHZVnFHgIRESlE0zRomlbsYdAAYOAjAIBpmujs7IRhGH1+cVuWhY8//hjTpk2DYRiDNEJviEaj2Lx5M6ZNm1bsoSivvb0du3btwgEH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",
"text/plain": [
"<Figure size 800x800 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def compute_velocity_model(azimuth, elevation, interpolate):\n",
" filename = list(output_csv.temp_files)[0]\n",
" \n",
" df = pd.read_csv(filename)\n",
" filename = filename.split('/')[-1]\n",
" \n",
" # Current EQ location\n",
" eq_lat = float(filename.split(\"_\")[0])\n",
" eq_lon = float(filename.split(\"_\")[1])\n",
" eq_depth = float(filename.split(\"_\")[2])\n",
"\n",
" # Define the region of interest (latitude, longitude, and depth ranges)\n",
" lat_range = (np.min([df.st_lat.min(), eq_lat]), np.max([df.st_lat.max(), eq_lat]))\n",
" lon_range = (np.min([df.st_lon.min(), eq_lon]), np.max([df.st_lon.max(), eq_lon]))\n",
" depth_range = (0, 50)\n",
"\n",
" # Define the number of nodes in each dimension\n",
" n_lat = 10\n",
" n_lon = 10\n",
" n_depth = 10\n",
" num_points = 100\n",
"\n",
" taup_model = TauPyModel(model='1066a')\n",
"\n",
" # Create the grid\n",
" lat_values = np.linspace(lat_range[0], lat_range[1], n_lat)\n",
" lon_values = np.linspace(lon_range[0], lon_range[1], n_lon)\n",
" depth_values = np.linspace(depth_range[0], depth_range[1], n_depth)\n",
"\n",
" # Initialize the velocity model with constant values\n",
" initial_velocity = 0 # km/s, this can be P-wave or S-wave velocity\n",
" velocity_model = np.full((n_lat, n_lon, n_depth), initial_velocity, dtype=float)\n",
"\n",
" # Loop through the stations and update the velocity model\n",
" for i in range(len(df)):\n",
" if ~np.isnan(df['velocity_p, km/s'].iloc[i]):\n",
"\n",
" ray_path = taup_model.get_ray_paths_geo(source_depth_in_km=eq_depth,\n",
" source_latitude_in_deg=eq_lat,\n",
" source_longitude_in_deg=eq_lon,\n",
" receiver_latitude_in_deg=df.st_lat.iloc[i],\n",
" receiver_longitude_in_deg=df.st_lon.iloc[i],\n",
" phase_list=['P', 'S'])\n",
"\n",
" # Create the interpolator objects for latitude, longitude, and depth\n",
" interp_latitude = interp1d(np.linspace(0, ray_path[0].path['lat'].max(), len(ray_path[0].path['lat'])), ray_path[0].path['lat'])\n",
" interp_longitude = interp1d(np.linspace(0, ray_path[0].path['lon'].max(), len(ray_path[0].path['lon'])), ray_path[0].path['lon'])\n",
" interp_depth = interp1d(np.linspace(0, ray_path[0].path['depth'].max(), len(ray_path[0].path['depth'])), ray_path[0].path['depth'])\n",
"\n",
" # Resample the ray path to N points\n",
" lat_values_interp = interp_latitude(np.linspace(0, ray_path[0].path['lat'].max(), num_points))\n",
" lon_values_interp = interp_longitude(np.linspace(0, ray_path[0].path['lon'].max(), num_points))\n",
" depth_values_interp = interp_depth(np.linspace(0, ray_path[0].path['depth'].max(), num_points))\n",
"\n",
" # Loop through the interpolated coordinates and update the grid cells with the average P-wave velocity\n",
" for lat, lon, depth in zip(lat_values_interp, lon_values_interp, depth_values_interp):\n",
" lat_index = find_closest_index(lat_values, lat)\n",
" lon_index = find_closest_index(lon_values, lon)\n",
" depth_index = find_closest_index(depth_values, depth)\n",
" \n",
" if velocity_model[lat_index, lon_index, depth_index] == initial_velocity:\n",
" velocity_model[lat_index, lon_index, depth_index] = df['velocity_p, km/s'].iloc[i]\n",
" else:\n",
" velocity_model[lat_index, lon_index, depth_index] = (velocity_model[lat_index, lon_index, depth_index] +\n",
" df['velocity_p, km/s'].iloc[i]) / 2\n",
"\n",
" # Create the figure and axis\n",
" fig = plt.figure(figsize=(8, 8))\n",
" ax = fig.add_subplot(111, projection='3d')\n",
"\n",
" # Set the plot limits\n",
" ax.set_xlim3d(lat_range[0], lat_range[1])\n",
" ax.set_ylim3d(lon_range[0], lon_range[1])\n",
" ax.set_zlim3d(depth_range[1], depth_range[0])\n",
"\n",
" ax.set_xlabel('Latitude')\n",
" ax.set_ylabel('Longitude')\n",
" ax.set_zlabel('Depth (km)')\n",
" ax.set_title('Velocity Model')\n",
" \n",
" # Create the meshgrid\n",
" x, y, z = np.meshgrid(\n",
" np.linspace(lat_range[0], lat_range[1], velocity_model.shape[0]+1),\n",
" np.linspace(lon_range[0], lon_range[1], velocity_model.shape[1]+1),\n",
" np.linspace(depth_range[0], depth_range[1], velocity_model.shape[2]+1),\n",
" indexing='ij'\n",
" )\n",
"\n",
" # Create the color array\n",
" norm = plt.Normalize(vmin=2, vmax=8)\n",
" colors_vel = plt.cm.plasma(norm(velocity_model)) \n",
" \n",
" # Plot the voxels\n",
" if interpolate:\n",
" interpolated_velocity_model = interpolate_vel_model(velocity_model, initial_velocity, lat_values, lon_values, depth_values, n_lat, n_lon, n_depth)\n",
" colors_interp = plt.cm.plasma(norm(interpolated_velocity_model))\n",
" ax.voxels(x, y, z, interpolated_velocity_model > 0, facecolors=colors_interp, alpha=0.5, edgecolor='k')\n",
" \n",
" ax.voxels(x, y, z, velocity_model > 0, facecolors=colors_vel, alpha=1, edgecolor='black')\n",
"\n",
" # Set the view angle\n",
" ax.view_init(elev=elevation, azim=azimuth)\n",
"\n",
"\n",
"compute_velocity_model(0, 40, False)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"35.766_-117.605_10.0_2019-07-04 17:33:49_3.csv\n",
"35.766_-117.605_10.0_2019-07-04T17:33:49-00_3.csv\n",
"35.766_-117.605_2019-07-04 17:33:49_3.csv\n",
"35.766_-117.605_2019-07-04 17:33:49_9.csv\n",
"current_vel_model.csv\n",
"testt\n"
]
}
],
"source": [
"!ls data/velocity"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"35.766_-117.605_10.0_2019-07-04 17:33:49_3.csv\n",
"35.766_-117.605_10.0_2019-07-04T17:33:49-00_3.csv\n",
"35.766_-117.605_2019-07-04 17:33:49_3.csv\n",
"35.766_-117.605_2019-07-04 17:33:49_9.csv\n",
"current_vel_model.csv\n",
"testt\n"
]
}
],
"source": [
"!ls '/Users/anovosel/Documents/phase-hunter/data/velocity'"
]
}
],
"metadata": {
"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.11.2"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
|