Spaces:
Runtime error
Runtime error
Added channel order input
Browse files- Gradio_app.ipynb +105 -342
- app.py +35 -6
- data/cached/AK_CAPN_2023-04-10T17:33:40.015179Z.mseed +0 -0
- data/cached/AV_KENI_2023-04-10T17:33:41.392981Z.mseed +0 -0
- data/cached/CI_SLA_2023-04-10T17:33:40.190746Z.mseed +0 -0
- data/cached/GS_CA09_2023-04-10T17:33:38.249774Z.mseed +0 -0
- data/cached/PB_B916_2023-04-10T17:33:42.213172Z.mseed +0 -0
- data/cached/PB_B917_2023-04-10T17:33:42.616354Z.mseed +0 -0
- data/cached/PB_B921_2023-04-10T17:33:39.103517Z.mseed +0 -0
- data/picks.csv +1 -4
- test_no_p.npy +3 -0
Gradio_app.ipynb
CHANGED
@@ -2,14 +2,14 @@
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
-
"execution_count":
|
6 |
"metadata": {},
|
7 |
"outputs": [
|
8 |
{
|
9 |
"name": "stdout",
|
10 |
"output_type": "stream",
|
11 |
"text": [
|
12 |
-
"Running on local URL: http://127.0.0.1:
|
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:
|
21 |
],
|
22 |
"text/plain": [
|
23 |
"<IPython.core.display.HTML object>"
|
@@ -30,7 +30,7 @@
|
|
30 |
"data": {
|
31 |
"text/plain": []
|
32 |
},
|
33 |
-
"execution_count":
|
34 |
"metadata": {},
|
35 |
"output_type": "execute_result"
|
36 |
},
|
@@ -38,215 +38,7 @@
|
|
38 |
"name": "stdout",
|
39 |
"output_type": "stream",
|
40 |
"text": [
|
41 |
-
"
|
42 |
-
"Finished downloading inventory\n",
|
43 |
-
"Processing CI.CCC...\n",
|
44 |
-
"Downloading waveform for CI_CCC_2019-07-04T17:33:40.494920Z\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 for CI_WBM_2019-07-04T17:33:40.063616Z\n",
|
68 |
-
"Skipping CI_WBM_2019-07-04T17:33:40.063616Z\n",
|
69 |
-
"Processing CI.WCS2...\n",
|
70 |
-
"Downloading waveform for CI_WCS2_2019-07-04T17:33:40.200958Z\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 for CI_WRC2_2019-07-04T17:33:38.698099Z\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 for CI_WVP2_2019-07-04T17:33:39.650402Z\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_3502/4124724611.py:273: 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_3502/4124724611.py:273: 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_3502/4124724611.py:280: 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 35.98249, -117.80885 has P velocity 4.13660431013202 and S velocity 2.2622770044299756\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_3502/4124724611.py:365: 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]],\n",
|
144 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:365: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n",
|
145 |
-
" output_picks = output_picks.append(pd.DataFrame({'station_name': [names[i]],\n"
|
146 |
-
]
|
147 |
-
},
|
148 |
-
{
|
149 |
-
"name": "stdout",
|
150 |
-
"output_type": "stream",
|
151 |
-
"text": [
|
152 |
-
"Station 35.69235, -117.75051 has P velocity 3.4155476453388767 and S velocity 1.67967367867923\n",
|
153 |
-
"Plotting waveform 3/3\n",
|
154 |
-
"Station 36.11758, -117.85486 has P velocity 4.745724852828504 and S velocity 2.6483289549749593\n",
|
155 |
-
"Plotting stations\n"
|
156 |
-
]
|
157 |
-
},
|
158 |
-
{
|
159 |
-
"name": "stderr",
|
160 |
-
"output_type": "stream",
|
161 |
-
"text": [
|
162 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:365: 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]],\n",
|
164 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:385: UserWarning: FixedFormatter should only be used together with FixedLocator\n",
|
165 |
-
" ax[i].set_xticklabels(ax[i].get_xticks(), rotation = 50)\n"
|
166 |
-
]
|
167 |
-
},
|
168 |
-
{
|
169 |
-
"name": "stdout",
|
170 |
-
"output_type": "stream",
|
171 |
-
"text": [
|
172 |
-
" station_name st_lat st_lon starttime p_phase, s \\\n",
|
173 |
-
"0 CI.JRC2 35.98249 -117.80885 2019-07-04T17:33:39.947494Z 7.320212 \n",
|
174 |
-
"1 CI.SRT 35.69235 -117.75051 2019-07-04T17:33:38.029990Z 4.532020 \n",
|
175 |
-
"2 CI.WMF 36.11758 -117.85486 2019-07-04T17:33:41.867962Z 9.504385 \n",
|
176 |
-
"\n",
|
177 |
-
" p_uncertainty, s s_phase, s s_uncertainty, s velocity_p, km/s \\\n",
|
178 |
-
"0 0.020417 13.385108 0.028439 4.136604 \n",
|
179 |
-
"1 0.017490 9.215676 0.019568 3.415548 \n",
|
180 |
-
"2 0.015920 17.031569 0.046738 4.745725 \n",
|
181 |
-
"\n",
|
182 |
-
" velocity_s, km/s \n",
|
183 |
-
"0 2.262277 \n",
|
184 |
-
"1 1.679674 \n",
|
185 |
-
"2 2.648329 \n"
|
186 |
-
]
|
187 |
-
},
|
188 |
-
{
|
189 |
-
"name": "stderr",
|
190 |
-
"output_type": "stream",
|
191 |
-
"text": [
|
192 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:503: MatplotlibDeprecationWarning: Unable to determine Axes to steal space for Colorbar. Using gca(), but will raise in the future. Either provide the *cax* argument to use as the Axes for the Colorbar, provide the *ax* argument to steal space from it, or add *mappable* to an Axes.\n",
|
193 |
-
" plt.colorbar(m)\n"
|
194 |
-
]
|
195 |
-
},
|
196 |
-
{
|
197 |
-
"name": "stdout",
|
198 |
-
"output_type": "stream",
|
199 |
-
"text": [
|
200 |
-
" station_name st_lat st_lon starttime p_phase, s \\\n",
|
201 |
-
"0 CI.JRC2 35.98249 -117.80885 2019-07-04T17:33:39.947494Z 7.320212 \n",
|
202 |
-
"1 CI.SRT 35.69235 -117.75051 2019-07-04T17:33:38.029990Z 4.532020 \n",
|
203 |
-
"2 CI.WMF 36.11758 -117.85486 2019-07-04T17:33:41.867962Z 9.504385 \n",
|
204 |
-
"\n",
|
205 |
-
" p_uncertainty, s s_phase, s s_uncertainty, s velocity_p, km/s \\\n",
|
206 |
-
"0 0.020417 13.385108 0.028439 4.136604 \n",
|
207 |
-
"1 0.017490 9.215676 0.019568 3.415548 \n",
|
208 |
-
"2 0.015920 17.031569 0.046738 4.745725 \n",
|
209 |
-
"\n",
|
210 |
-
" velocity_s, km/s \n",
|
211 |
-
"0 2.262277 \n",
|
212 |
-
"1 1.679674 \n",
|
213 |
-
"2 2.648329 \n"
|
214 |
-
]
|
215 |
-
},
|
216 |
-
{
|
217 |
-
"name": "stderr",
|
218 |
-
"output_type": "stream",
|
219 |
-
"text": [
|
220 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:503: MatplotlibDeprecationWarning: Unable to determine Axes to steal space for Colorbar. Using gca(), but will raise in the future. Either provide the *cax* argument to use as the Axes for the Colorbar, provide the *ax* argument to steal space from it, or add *mappable* to an Axes.\n",
|
221 |
-
" plt.colorbar(m)\n"
|
222 |
-
]
|
223 |
-
},
|
224 |
-
{
|
225 |
-
"name": "stdout",
|
226 |
-
"output_type": "stream",
|
227 |
-
"text": [
|
228 |
-
" station_name st_lat st_lon starttime p_phase, s \\\n",
|
229 |
-
"0 CI.JRC2 35.98249 -117.80885 2019-07-04T17:33:39.947494Z 7.320212 \n",
|
230 |
-
"1 CI.SRT 35.69235 -117.75051 2019-07-04T17:33:38.029990Z 4.532020 \n",
|
231 |
-
"2 CI.WMF 36.11758 -117.85486 2019-07-04T17:33:41.867962Z 9.504385 \n",
|
232 |
-
"\n",
|
233 |
-
" p_uncertainty, s s_phase, s s_uncertainty, s velocity_p, km/s \\\n",
|
234 |
-
"0 0.020417 13.385108 0.028439 4.136604 \n",
|
235 |
-
"1 0.017490 9.215676 0.019568 3.415548 \n",
|
236 |
-
"2 0.015920 17.031569 0.046738 4.745725 \n",
|
237 |
-
"\n",
|
238 |
-
" velocity_s, km/s \n",
|
239 |
-
"0 2.262277 \n",
|
240 |
-
"1 1.679674 \n",
|
241 |
-
"2 2.648329 \n"
|
242 |
-
]
|
243 |
-
},
|
244 |
-
{
|
245 |
-
"name": "stderr",
|
246 |
-
"output_type": "stream",
|
247 |
-
"text": [
|
248 |
-
"/var/folders/_g/3q5q8_dj0ydcpktxlwxb5vrh0000gq/T/ipykernel_3502/4124724611.py:503: MatplotlibDeprecationWarning: Unable to determine Axes to steal space for Colorbar. Using gca(), but will raise in the future. Either provide the *cax* argument to use as the Axes for the Colorbar, provide the *ax* argument to steal space from it, or add *mappable* to an Axes.\n",
|
249 |
-
" plt.colorbar(m)\n"
|
250 |
]
|
251 |
}
|
252 |
],
|
@@ -302,17 +94,41 @@
|
|
302 |
" \n",
|
303 |
" return resampled_waveform\n",
|
304 |
"\n",
|
305 |
-
"def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
" waveform = np.load(waveform)\n",
|
307 |
" print('Loaded', waveform.shape)\n",
|
308 |
"\n",
|
309 |
" if len(waveform.shape) == 1:\n",
|
310 |
" waveform = waveform.reshape(1, waveform.shape[0])\n",
|
311 |
-
"
|
|
|
|
|
|
|
312 |
" if sampling_rate != 100:\n",
|
313 |
" waveform = resample_waveform(waveform, sampling_rate, 100)\n",
|
314 |
" print('Resampled', waveform.shape)\n",
|
315 |
"\n",
|
|
|
316 |
" orig_waveform = waveform[:, :6000].copy()\n",
|
317 |
" processed_input = prepare_waveform(waveform)\n",
|
318 |
"\n",
|
@@ -326,12 +142,12 @@
|
|
326 |
" return processed_input, p_phase, s_phase, orig_waveform\n",
|
327 |
"\n",
|
328 |
"\n",
|
329 |
-
"def mark_phases(waveform, uploaded_file, p_thres, s_thres, sampling_rate):\n",
|
330 |
"\n",
|
331 |
" if uploaded_file is not None:\n",
|
332 |
" waveform = uploaded_file.name\n",
|
333 |
"\n",
|
334 |
-
" processed_input, p_phase, s_phase, orig_waveform = make_prediction(waveform, sampling_rate)\n",
|
335 |
"\n",
|
336 |
" # Create a plot of the waveform with the phases marked\n",
|
337 |
" if sum(processed_input[0][2] == 0): #if input is 1C\n",
|
@@ -506,10 +322,12 @@
|
|
506 |
" if len(waveforms) == 0:\n",
|
507 |
" print('No waveforms found')\n",
|
508 |
" fig, ax = plt.subplots()\n",
|
509 |
-
"
|
|
|
510 |
" fig.canvas.draw();\n",
|
511 |
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
|
512 |
" plt.close(fig)\n",
|
|
|
513 |
" output_picks = pd.DataFrame()\n",
|
514 |
" output_picks.to_csv('data/picks.csv', index=False)\n",
|
515 |
" output_csv = 'data/picks.csv'\n",
|
@@ -833,13 +651,16 @@
|
|
833 |
" info=\"Sampling rate of the waveform\",\n",
|
834 |
" interactive=True,\n",
|
835 |
" )\n",
|
|
|
|
|
|
|
836 |
"\n",
|
837 |
" button = gr.Button(\"Predict phases\")\n",
|
838 |
" outputs = gr.Image(label='Waveform with Phases Marked', type='numpy', interactive=False)\n",
|
839 |
" \n",
|
840 |
" button.click(mark_phases, inputs=[inputs, upload, \n",
|
841 |
" P_thres_inputs, S_thres_inputs,\n",
|
842 |
-
" sampling_rate_inputs], \n",
|
843 |
" outputs=outputs) \n",
|
844 |
" with gr.Tab(\"Select earthquake from catalogue\"):\n",
|
845 |
"\n",
|
@@ -971,60 +792,77 @@
|
|
971 |
},
|
972 |
{
|
973 |
"cell_type": "code",
|
974 |
-
"execution_count":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
975 |
"metadata": {},
|
976 |
"outputs": [
|
977 |
{
|
978 |
"data": {
|
979 |
"text/plain": [
|
980 |
-
"[<matplotlib.lines.Line2D at
|
981 |
]
|
982 |
},
|
983 |
-
"execution_count":
|
984 |
"metadata": {},
|
985 |
"output_type": "execute_result"
|
986 |
},
|
987 |
{
|
988 |
"data": {
|
989 |
-
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGdCAYAAAAvwBgXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABMTElEQVR4nO3dd3wU1doH8N/sbrLphYSEFjrSpQoionhBEbGgXq8FFb1ebPAq6lVBxXoltlexYhcsgOUV7CCiwFUp0qR3kBBIQkslbLac948lSzbZvjM7M5nf9/NZMbMzc56Z3Z155pwzZyQhhAARERGRCkxqB0BERETGxUSEiIiIVMNEhIiIiFTDRISIiIhUw0SEiIiIVMNEhIiIiFTDRISIiIhUw0SEiIiIVGNRO4BAXC4XDhw4gNTUVEiSpHY4REREFAIhBCoqKtCiRQuYTIHrPDSdiBw4cAB5eXlqh0FEREQRKCgoQKtWrQLOo+lEJDU1FYB7Q9LS0lSOhoiIiEJRXl6OvLw8z3k8EE0nIrXNMWlpaUxEiIiIdCaUbhXsrEpERESqYSJCREREqmEiQkRERKphIkJERESqYSJCREREqmEiQkRERKphIkJERESqYSJCREREqmEiQkRERKphIkJERESqYSJCREREqmEiQkRERKphIqJX+1cBK98BhFA7EiIioohp+um7FMC7w9z/puQC3S5VNxYiIqIIsUZE7w5vUzsCIiKiiDERISIiItUwESEiIiLVMBEhIiIi1TARISIiItUwEYmVXT8Dm+bJv17evUtERDrG23dj5aPL3f+22gykt1Q3FiIiIo1gjUisHT+sdgRERESawURE7yS1AyAiIoocExEiIiJSDRMRIiIiUg0TEb3jXTNERKRjTERijU/LJSIi8mAiQkRERKphIkJERESqYSJCREREqmEiQkRERKphIkLadKIc2Psr4HKpHQkRESmIiQhp0/sXAjNGAavfVzsSIiJSEBMR0qaSTe5/13+mbhxERKSoiBORpUuX4pJLLkGLFi0gSRLmzZvn9b4QAo8++iiaN2+OxMREDB8+HDt27Ig2XiIiImpEIk5Eqqqq0KtXL7z++us+33/uuefwyiuv4M0338SKFSuQnJyMESNG4MSJExEHS0RERI2LJdIFR44ciZEjR/p8TwiBadOm4ZFHHsFll10GAPjwww+Rm5uLefPm4Zprrom0WCJ1CAFIfNQxEZHcFOkjsmfPHhQVFWH48OGeaenp6Rg4cCCWLVvmdzmbzYby8nKvV+Mj9xDvHDJecTt/Ap5rB2z5Vu1IiIgaHUUSkaKiIgBAbm6u1/Tc3FzPe77k5+cjPT3d88rLy1MiPKLwfHwlUH0M+HSM2pFoW0URsHoGUFOldiREpCOaumtm8uTJKCsr87wKCgrUDkkH2FxAGvH+COCbu4EFD6sdCRHpiCKJSLNmzQAAxcXFXtOLi4s97/litVqRlpbm9SIinTi21/3v9vmqhkFE+qJIItKuXTs0a9YMixYt8kwrLy/HihUrMGjQICWK1CaXU+0IiIiINC3iu2YqKyuxc+dOz9979uzBunXr0KRJE7Ru3RoTJ07Ef/7zH3Tq1Ant2rXDlClT0KJFC4wePVqOuLXvl6nAsteBW5cA2R3VjkbH2PRERNSYRZyIrFq1Cuedd57n73vvvRcAMHbsWMyYMQMPPPAAqqqqcOutt6K0tBRnn3025s+fj4SEhOij1oMlz7r/XfQ4cPXHp6YL3jUTnsa+fY0Rk0ciCl3EicjQoUMhApxUJUnCk08+iSeffDLSIogokJ//475D5cJ8tSOph8kjEYVOU3fNEFGIHDXA0ueB5W8AZfvVjoaIKGJMRJRWv9YolqNzVhS7x8DY+n3syqQYqfO9ctaoE8L+VcB7F7j/JSKKEBMR3QuQ2Myf5B4VdM61sQtHduxvoFnvXQAUrADeO7/eG/zMiCh0TEQas6pDakcgA/Y30Cxx8vZ04ar/RsxDISL9YiISa7xrhuQg+/eIiEgdTEQas73/VTsCMiQ2zRBR6JiINFbVx8Kb32nX6N0XPKkRETVmTEQaK4ctvPk/GAm81B34a5ky8RAREfnAREQtNVXAsb/UjuKU/X+4/133ceD5Yq2m0v001/2r1Y6EiIgUwERELS/3Al4+HSjZonYk2la8EVj2GvDu39SOxJhqjgPrZgFVh9WOhIgaKSYiMXfybofaW2t3/KhQOexboTk7fwI+vR6o1NFt1T8+DMy7A5gxSu1IiKiRivhZM9RI8a5Q5Xx8pftfsxX4+3tRrixGH9Tmr9z/Htoa+jKxHD2YiHSPNSLhEAKYdQ0w+1qO40CRqzgo8wrrnPjL9gPHj8q8fiIi5TARCUfVYWD7D8C278O/PdZD5qvF8gPuq1aXU971krb5SoSrjrjvfHquXezjqYtJOhGFgYlIWCI8wCp5YF79AfDZje5/tergn8D0wcCOhWpH4lZ12P30WgBw1R+eXMdKNqkdARFR2JiIxJxCScmuX5RZrxxmXeO+++WTv6sdCXB0N/B8B+CNM4GCP4Dn2gJrPlQ7qghouNZBkoDSAuC3V4ATZWpHQ0Qax0SElGcrVzuCU7Z+5/736C7g87HuE+XX/6NuTI3Ru8OBhVOA7+5TOxIi0jgmIpHa9CXw3xeDz6dWeznvXNCwCD4bRw1wdM+pv7XeD6OyyP3v7sWqhkFE2sdEJFLf3QcsegIoVGHEzy3fKrhyjZ/gGgUf+zhYYjHzYuCV3u6xSOSw7HXg8XRg+XR51kdEFCFDjiNSVm1HryfcA4l1zEnBa9f1wYXTAj+p9toBrfHjyg1YneA9/abX52Oxq6jB/HtPzvfj5iJMmfoTVpycfulrv+GSkZkYd/Lvqd9vwdvffBdy7P93x1no9+mYBtMXbCrCbZPc6+nXJhN//bUXq+rE2nZS4DJq4/18VQHuXx56PLUScQIvdduFhze3Qk/TblxiXo5H7TehConYaHUg5WQlwKItxbhl5irPchd2b4ZNB8tQcLTaZzx1tZ30HR4Z1RX/+S74aLR/65KDn7eW4JFRXbFgUxH+2Ou+y+lf5i14JM49z4GyarSQTq3bn7qxPP71Jsz4fW/Q8uu6eXBbfPDbXs96Vuw5gqtPlnff+achbcP7uLL8Y8zt9RamLPOdkOxNcH+Dvpv5LMbbbUjCCWw+ub4hz/+CArEZg0ybMDvee3t+uHsIRr7s/m5/eedZuOKN35GJcqxNeMg94/xJaDuvtd/YV1trkOVjH7XMSMRvdeZrO+k7z/bV3a+HKm04Y9J3+OiWAXhp4Xas2Vfqt6yEOBPO6pCN3YcqMePmARj6wuIG88z85wBUnLBj6ndbMP36frjsdXcUT43ugSnzNjaYPyMpDqXH7X7LrO+03BSkJsRh9V/HMHF4J2Qlx2Pq91tRbW94V9rXEwbj/s/XY1txhWdam6wk/HXkeMjlBbP5yRGwWszo8ND3nmlDOzfF4m0NB8V7ZFRX/GtIewDACbsTXabM97xntZhgc/jumL1g4jkY+/5KFJWfCBjLDWe2wVOje+D2j1Zj/qZTx7zXr+uLM9pmYsDURZ5pT1/eAw/PdX8eKx4ahuwUq9c21PfiP3ohKd6C2z8OfmGXnhiHsmo7Uq0WVNgcQeevdWb7Jli+2/et7X1aZ2DtvlJc1rsF/n1BZwx57lSfO4tJQqvMROw9chyjejbHdxuC337fMScFO0sqcXbHbPy603tU4vHndcAXq/ejuLzh88CyU6w4XOmeHmeWYHcGvkBpl50Mi0nCjpJKz7ROOSlef/uSm2ZFbloCujRLxXN/7xV0e5RmyERkZp0Tyc6SStwyY5X/mU+avXIfsvy8l4YqlCPZ53sCEoorbECdk9nT32/BOB8n2lDc/MFKrA8yz+q/jiE7stVH7HHLh7hw92K0j2+J00yFAIBDIgPPOK6FVKcGoG4SAgDzNx3EP83zscPUEv91nR60nFCSEAD4eWtJ0PlFBE0kB5Z/jnfiluJ++60oRWrAeVviEI4iFR/8ttfvPP+7cDv2JrwBAOi+egqAJ0OKQwqx5qo2CQGAK974HQCQiJqQlg1UTmFptdd32v/ybje8tzLovCfsLs/n5isJAYCx759aT20SAsBnEgIgrCQEALYXnzqAT/tpR8B5L33ttwbT5ExCAGDu2kJ0zvX+nvlKQgD3d702Eflw2V6v9/wlIQAwYtrSkGL5aPlfeGp0D68kBADGz1qD6wZ6J7O1SQgA3PjeSky9omfAdd/72Z8hxQC4LyQBhJWEAPCbhADA2pMJ8lfrDuBgmXdC5nAJ7D35uYaShADu8wqABkkIALz+yy6/y9UmIQCCJiEAsOdwVYNpwZIQACgut6G43Ib1+8s0kYgYsmnG4fL+gAP9SIOZaPkC6xPGYbTpV5/v1z+Qh3oC8SeULycQXgPLuabQDwL+XGh2nyBqkxAAaCYdCbrcmaYteDTuI3wU/0zUMcTC2/Ev4Xzzajxg+TTgfO2lA/gt4W78Zr2rwXuRJEByivY7GIza29eYuIT7Fa76xzilOZz+j6F2lwtC632a6qiJ4nxAkTFkIiLnYbK3aTcA4D9x78u41ugF2kYJLqTBnUnnScWYGf9sbILyoSX0+TC1LCnwnUC1yV0TKfjVSa1QvpeS59/QD+ynSQWYE/8UzpDcw7RnShVBljglkqRC6USH9EUC+85TYMZMRCL4Udxq/gY3WjQyIFeUPorLx/qEceggFSJPUu4BbLW7WUtXyLE6RcZyi4Pt3/fjn8eZpi343Opu9vnW+kgswiIDkQJ8ByVJAh/CSYEYso9IuHJwDA/FzVY7DACACPFUGmius83uETj/YV6MJS512weHmtepWr5eSV7/7/vTtqIGfU070EqKba1T3cSItSNR0lGTBlGkDJmIBMrefUmSAvcmD1wWBToZXWJeHsNIGovQTk6vxr2KC8wq3F5OVAebZigYNs3EWP1q9HBDCTeJqjXGHNr4E5HuG1/NA3JfDTdH8M6v8tDuVWiWVI7frHfhAcucoPNqIQnRUrOcLvEMTgZgzEQk5uUJn/8fS0+f7EwrwbtHuJ5OFP+O+yzqddTdWl/bbkUNFsY/gKmWd6IsJ/rPORnV6CAVek0baNqKltIR3GCRaWAzIvKi3cuQxsuQiUhdaahEE1Gq2PqDfanD/dJLaDiwku/1+k4wrvBzm7EexCKJu9C0Ep1MhbjOEu1DBMOPtf72LbVOxCLr/Thd8j/ugLsk7SaT7CMSJSF0deurL5LEJmoKzJCJSN3azvUJt+JH5y1IRrX/BaIpS8Z1ZaEMv5tu9fleqCej4UGq65U+cYwx/wQLwhuIyDeBTIT3ML2u0l/oYdoTcB6Thk6cWSdvsx1mXqtaDEwk9CnSJtyIywtQnATp5J0zRL4ZNBFp+KNoFeA2VjmvOKNZ042WhcjwMy5FJCcMNa6kn457HzeZF0S9nsctM7E24XaMNK0IPjMACxz4wToZo82/B5zvobhZUcemZbXjxxDFEtMQCsSQiYia5lkfDamjoVpCTU6iOaH1M22PeNlaN1nczwoKdV9aEXyobxNcaCqVRRVXKIQI97AsX63E+oRxwWeKkpabivQoktqEUG/zjwVWhlAwTEROCjwSqbw/6jstX0e4pDYOLreZv8H6hHG42hy4H4WeqvXvsXyB5+Lelm19Rj72aqFzNmmLnpIRHYXaaDARUVxkB2IravAP8y9oimOyRhPsRyZBoLVUjLXWW/3WNkw+Objbs3HR3VkSrivMvyIDoQ9PHkwaTj2g7G7Ll/i7ObSHf0VLksL7Tqh5MvdXuyHn50BExmbIRCSW2XlvU+A7HvyZZJmN5+LewVzrYwCAIab1uNsyN6RlO0v7/PYlCUW+5V1kSpW40/I1moU4dkc41fHRVN0/ZJGvD0eaJO+TUqMXXcKRDeWblWqNt3zl9726ny+baQiIfefZaLAOL/YMO7JqW+kgSkRmnWn+v37hHkw7Sfs9/x+sz4G/NQ83rQGAk8Nzi5CfTttd2ovvrA+FNK8/yXVGkj3NtB9FrqyI1qPEoadlveHK1Tq8BauliHUtRgqO49X412JWXiJswWciwwh414ye2mVIFYZMRLIrtmCx9T4cEmmKrP/L+MdkXd/fTKHfvjnEtF7WsuU4hPAw5K21VCz7OttLB2VfpxzYRyR6uh9HBPrqI0KxZ8immXZHFgMAmgZ5lHukUqXQxyQJ5RBzaZBbTt3rCe2XHkp5CagJaV1ylBUrcjcRBFtfoBNwC+ko+krR3zmktHNNf3rGMiEiUoohExFfpxA5rtxycRRxUQzWlYYq5FvewQBpS9jLynnl2cVUIMt6avez0glJa6kYr8S9im7SXoVLks8oc2jjnwDq1SjNjH9WpZIpWlrqk8HaEArGkE0zSkiRTmBFwgRsdrWJeB2TLLNxreUXXGv5BftFdkTrCH6lHt78WidB4L24F9DJVIiLTCvQ0fax3/m0rrdpN7JRhsNID3PJ2H+Gev/eUGwxGaFADFkj4ouvA+tI0wosjr8H3cO40u5m+qvBtFB/g23q9B1oVa9TpjIktED9ciI7Yat5mu9kcj8YziK5gswZnktMvyNPgf4cgP/9tdJ6Z4NpwZOohu9/Gx9dh2W58PxDRMEYtEYktEfWT49/GQDwRvwrikekhhvMPyLZouTdD75PoNqvm3CL5i6USE/ApjDHGPGnh2mvLOshdQno5a4T/zG6H3qnh204Seedg/XIkDUiWv1dR9N8MMK8KuxBppKl2NyCKefurr+HQm0i6CgVyhhFbJt6oukYS8akqSHe9ZSEkCoUS0ScTiemTJmCdu3aITExER06dMBTTz2lkVvRfNWI6N+jcR/Jvs5slGGkaUVET8xNgXs8EjOcssVT/3MK5SR8qel3fGV9VLYY5BBOHwsz5G1ykkO4d2kNNa3Fm3EvoUmYT0w2usZwXJIk7V78+aSrYBsHxZpmnn32WUyfPh0zZ85E9+7dsWrVKtx8881IT0/HXXfdpVSxIfJ/8pLgQj9pOzaLtjGJRM6vfAfpALYhT8Y1Av8b/yYA4Hn7P/C6c3RYy7Y7ObaFVfKdxPSRdkQVW6iutyyUfZ2xrKWI/NlE2jEj/nkAQBUScJ/9DpWj0ZdILt40cb1XB8/tFIhiicjvv/+Oyy67DKNGjQIAtG3bFrNnz8bKlSuVKlIWN5kX4LG4j7DW1VG2dbaXDsi2LrVcYF4VdiISTO3w9eEI9fhqRQ3ejHsJi129wy5DDheaY/c9j+UxvhmOID/u3ZAHUKsfW47Mz05q7CLNJ7R04tdQKKRRijXNnHXWWVi0aBG2b3cP3PTnn3/i119/xciRI/0uY7PZUF5e7vVSRsOfxnXmRZDgwtXmxQCAPqadspX2k/UBv+/VPdBo+QersQusoK42/4LzzH/iibiZMS+7j7QDvU27A86j19tfn457H+eZ/0QbU4nX9P7SVpUiatwe/WoTrn57ecjz/7S5GG0nfYfn5m9TJJ4Tdt/NrLNX7vO7zJ/7y3DhtP8qEo8S/iwoVTuEmGo76Ts8+IW8I3KHS7FEZNKkSbjmmmvQpUsXxMXFoU+fPpg4cSLGjBnjd5n8/Hykp6d7Xnl58jYz1PJ1ChhjWRSzp682Rr5OrBIE2khFIc0bDZdouL7a/im1ccRSJ9P+4DPpVI7ku0ajp2lPSMvrNQHTi399uErR9X+ywn/CQfr16Sp5BrGMlGKJyGeffYZPPvkEs2bNwpo1azBz5ky88MILmDnT/xXq5MmTUVZW5nkVFCi0c/wcC3tKe3R9B4IckQe4CS+idX0YF9rD+iLl//PS7+cYLj1/Z0lfqmyRjxxN5I9ifUTuv/9+T60IAPTs2RN//fUX8vPzMXbsWJ/LWK1WWK1WpULyCHRK7azjq1kJwU+/kZ60Ir2SrV+FrwS5xt4IR1fpLzxp+QCvOK7AYaSjr7QdJcjEftE0pOUbc+pQdzA+JkmNC+uzSAmKJSLHjx+HyeRd4WI2m+FyqX8ror8Bgm5U4O6KYO6zfIFyJGOO828xL1tOvh6OJvlNEPR/OGttOoQbTQvRWirBU47r8aX1cQBA2xOzQlpeziYKLZzs9f+JEpFaFGuaueSSS/D000/ju+++w969ezF37ly8+OKLuPzyy5UqUpeskh3PxL2rdhge/k5qtVPPNG1WrOyzTRtwl/lLSDKMmxGrE+NQ858YadL2nWByCjeB8jV/cxzBFaalEY1NQ+rS0t041HgoViPy6quvYsqUKbjzzjtRUlKCFi1a4LbbbsOjj6o/sFSCvVTtEBQRynVxtFfig2RJRHxH+nF8PgBgl2gRYEntHQn/Hfe519/aizB0/zJ/h/6m7Rhv9z3Wjxy1Lz9b70OiVINceymmOy+Nen0UO/oYbp70RrFEJDU1FdOmTcO0adOUKiJiydXaHNfDX1NGLE++/sqKZQwtpUN+3wv1RHh/3GdyhaMQ//tzkmU2nnFcK8OawvdI3CcAgBHOP2RZX/3PS4JAolQDwF0DxkSEiIz5rBldX7P6p/RWtZGKkI0yGdYkZ/8I37fvasl5prVhzX+75RuFIgmdFXaf06NNSIeYN0a1PBE1PoZMRPSWh4RTHR7t0OP+3u9n2oEl1nsxxrIo5FiUUH/78kz+a0+04h7LFz6np+A4Pot/Iur1T7bMQieZH+rnNOihgYhiT7GmGYo99e+d0Ca18844H50yBYB/Wb7HAFP0I2BeYF6NC8yro15PXU6Yw5o/ku/eYPMm+Kl4IY1iFxFSgiETES3+lnpIgYcEl8PZpg0YYVZ25MW6gt2B408Xk7wD2cX66bUNt6/hN26gaQtaS8qPsRKpcGtE/P2mtHBrMRFpG+tfNeJb6yNoLRVHtY5UVAd8v/auFDmdLu2SfZ1XmH+VdX1yPjcoFPVPyr6ay/qadiJbUupZStELPxFhwmEEjbV/HanLoImINg+aLaSjUS3fwXQQA0zRPXzscvNv4ZUZ4MnC/k5Ol5iXI0uWTq/6EMm37Yf4B2WPw5+x5gVoCe++NuwjQr6waYaUYMijjd6y+nDuVDjfvEbBSOQT6mPkGwMBCWeZwrtbpKvMzVOBPBE3E78l3I26KZNLpkODFsd9ISJtMWQiwmNjbASq4UmXqmIYifpmxU9VO4Sg6tZuOcLurOr7RyVBIB2VUcVF2sFDJynBkIkIf0xEDTXBqecF+WuaCZRw+DPEtMHve5nQbj8ZIooNQyYiTEXUx86N2mORnJ7/dwn5Dg2BPmsLnH7fI+1hHxFSgkETEX2dBLV80n447hNEsj+1vE3Rqr9tetnSunE7fSTrZjiRgJpYhkREBsBxRCgq2VK5TA/Ck8czlrfR2bRf7TC8NJYOm7sSbvD7nv8mm8CypAocEplRREWxpLeO/qQPxqwR4W9JVukIv+OpnCdnU52HBV5jWRzzcUOC0Usi0lX6K+JlI63hGmf5NuIyKfbYNENKMGQiwt+S+iI9cenhpK6HGH2ZcvLJu0AkD96L7PPU554iIjkZMhHRG62f2CJJKiJ9SJse+5boMebh5vCeGOxPsC3X474hInkxESFV3B/3mdohkIz8jcgbLIVmIkJEhkxEtF2/oD+xPJlovXYI8HXXjPZjjlYP016/7wXa+sa/Z4goGEMmIuxxpV9dTfvwnOUttcMgmbBGRF8kHjtJAcZMREhWsbzibyqV4R+WJTErj5TVU9qtdggUBqYhpARDJiJ6uwo7XeMHa73tTyUl4YTXUOmAfgY0U0bgrW9nKo5RHCSHJ7/VzphB1HgYMxHRWVrfwWScJ9XqXW/TTpjgUjsMIiLdMGQiYtjNJsX5qh3SWd5LRBRThjwjsymBlGSEu2SIiORiyESESCm+UhAjp73xcOCV+NfUDoOINIyJCJHMjJx41Jcg2dUOgYg0jokIRY0NEUREFCkmIkRERKQai9oBqIOV53Ji599TRpj+wA2Wn7ym9TZpexwYIiI1sUaESEb1kxAiIgrMoIkIezXIiberEhFRpIyZiAg2JciJTTNERBQpYyYiREREpAlMRIhIZaxRIzIyQyYiQm9PvdM4KzhoFUWOTXtExmbIRERiHxFZ/W/8m2qHQDrGywIiYzNkIkJE2sEaESJjYyJCRKpiIkJkbExEiEhVbJohMjaDJiK8AiPSCtaIEBmbQRMRItIKJiJExmbQRISVwURERFpgyETkSMvz1A6BiE5ijQiRsRkyEXFaktUOgYiIiKBwIlJYWIjrr78eWVlZSExMRM+ePbFq1SoliyQinWGNCJGxWZRa8bFjxzB48GCcd955+OGHH9C0aVPs2LEDmZmZShUZMsEuIkSawZ8jkbEplog8++yzyMvLwwcffOCZ1q5dO6WKC4vECzAizWCNCJGxKdY08/XXX6N///646qqrkJOTgz59+uCdd94JuIzNZkN5ebnXi4gaNyYiRMamWCKye/duTJ8+HZ06dcKCBQtwxx134K677sLMmTP9LpOfn4/09HTPKy8vT6nwiEgj2DRDZGyKJSIulwt9+/bF1KlT0adPH9x6660YN24c3nzT/5NaJ0+ejLKyMs+roKBAkdjYR4RIO1gjQmRsiiUizZs3R7du3bymde3aFfv27fO7jNVqRVpamtdLCewjQqQl/EESGZliicjgwYOxbds2r2nbt29HmzZtlCqSiHSIFZRExqZYInLPPfdg+fLlmDp1Knbu3IlZs2bh7bffxvjx45UqMmRsmiHSDjbNEBmbYonIGWecgblz52L27Nno0aMHnnrqKUybNg1jxoxRqkgiIiLSGcXGEQGAiy++GBdffLGSRUSEfUSItIM1IkTGZshnzRCRdrCllMjYDJmIsI8IkXawRoTI2AyZiPC4R6QdvC4gMjZjJiLMRIg0gzUiRMZm0ESEiLSDiQiRkRk0EWFlMJFW8NdIZGwGTUSISCucPAwRGRqPAESkqiNIVzsEIlIRExEiIiJSDRMRIiIiUg0TESIiIlINExEiIiJSDRMRIiIiUg0TESIiIlKNIRMRjuNIRESkDYZMRIiIiEgbmIgQERGRapiIEBERkWqYiBAREZFqmIgQERGRapiIEBERkWqYiBAREZFqmIgQERGRapiIEBERkWqYiBAREZFqmIgQERGRapiIEBERkWqMmYjwqXdERESaYMxEhIiIiDSBiQgRERGphokIERERqYaJCBEREamGiQgRERGphokIERERqcaYiYgkqR0BERERwaiJiOBAIkRERFpgzESEiIiINIGJCBEREanGmIkI+4gQERFpgjETEfYRISIi0gRjJiJ86h0REZEmGDQRISIiIi1gIkJERESqMWgiwqYZIiIiLYhZIvLMM89AkiRMnDgxVkUSERGRxsUkEfnjjz/w1ltv4fTTT49FcURERKQTiicilZWVGDNmDN555x1kZmYqXRwRERHpiOKJyPjx4zFq1CgMHz486Lw2mw3l5eVeL2WwjwgREREAxJvV7S5qUXLlc+bMwZo1a/DHH3+ENH9+fj6eeOIJJUMiIiKiOmb88wxVy1csDSooKMDdd9+NTz75BAkJCSEtM3nyZJSVlXleBQUFSoVHREREANpmJatavmI1IqtXr0ZJSQn69u3rmeZ0OrF06VK89tprsNlsMJvNXstYrVZYrValQiIiIqJ61H78mmKJyLBhw7BhwwavaTfffDO6dOmCBx98sEESElPsIkJERKQJiiUiqamp6NGjh9e05ORkZGVlNZhORERE6pCgbpWIQUdWJSIiIi1Q9K6Z+hYvXhzL4oiIiCgItfuIGLNGRLCTCBERkRYYMxEhIiIiTWAiQkREZGAqt8wwESEiIiL1GDQRYR8RIiIiAKpXiRg0ESEiIiItYCJCRERkYBzQTBVsmiEiItICgyYiREREBHBAMyIiIjIwJiJEREQGxnFE1MAh3omIiDTBmIkIERERAQAklTuJMBEhIiIi1TARISIiMjD2EVED+4gQERFpgjETESIiIgLAcUSIiIjIwJiIEBERGRifNaMCic+aISIicmPTDBEREaklPTFO1fKZiBAR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F2w2G/dVHcOGDcOGDRuwbt06z6t///4YM2aM5/+5r/yrrKzErl270Lx5c36v6hk8eHCDIQa2b9+ONm3aANDJ8T3q7q46M2fOHGG1WsWMGTPE5s2bxa233ioyMjK8elc3RhUVFWLt2rVi7dq1AoB48cUXxdq1a8Vff/0lhHDf3pWRkSG++uorsX79enHZZZf5vL2rT58+YsWKFeLXX38VnTp18rq9q7S0VOTm5oobbrhBbNy4UcyZM0ckJSXp6vbdO+64Q6Snp4vFixd73Tp4/Phxzzy33367aN26tfj555/FqlWrxKBBg8SgQYM879feOnjBBReIdevWifnz54umTZv6vHXw/vvvF1u2bBGvv/66Lm8dnDRpkliyZInYs2ePWL9+vZg0aZKQJEn8+OOPQgjuq0Dq3jUjBPdVXffdd59YvHix2LNnj/jtt9/E8OHDRXZ2tigpKRFCcF/VtXLlSmGxWMTTTz8tduzYIT755BORlJQkPv74Y888Wj++Gy4REUKIV199VbRu3VrEx8eLAQMGiOXLl6sdkuJ++eUXAaDBa+zYsUII9y1eU6ZMEbm5ucJqtYphw4aJbdu2ea3jyJEj4tprrxUpKSkiLS1N3HzzzaKiosJrnj///FOcffbZwmq1ipYtW4pnnnkmVpsoC1/7CID44IMPPPNUV1eLO++8U2RmZoqkpCRx+eWXi4MHD3qtZ+/evWLkyJEiMTFRZGdni/vuu0/Y7XaveX755RfRu3dvER8fL9q3b+9Vhl7885//FG3atBHx8fGiadOmYtiwYZ4kRAjuq0DqJyLcV6dcffXVonnz5iI+Pl60bNlSXH311V7jYnBfefvmm29Ejx49hNVqFV26dBFvv/221/taP75LQggRXZ0KERERUWQM1UeEiIiItIWJCBEREamGiQgRERGphokIERERqYaJCBEREamGiQgRERGphokIERERqYaJCBEREamGiQgRERGphokIERERqYaJCBEREamGiQgRERGp5v8Bjf6vxL9TJoUAAAAASUVORK5CYII=",
|
990 |
"text/plain": [
|
991 |
"<Figure size 640x480 with 1 Axes>"
|
992 |
]
|
993 |
},
|
994 |
"metadata": {},
|
995 |
"output_type": "display_data"
|
996 |
-
},
|
997 |
-
{
|
998 |
-
"name": "stderr",
|
999 |
-
"output_type": "stream",
|
1000 |
-
"text": [
|
1001 |
-
"Traceback (most recent call last):\n",
|
1002 |
-
" File \"/usr/local/lib/python3.9/site-packages/gradio/routes.py\", line 393, in run_predict\n",
|
1003 |
-
" output = await app.get_blocks().process_api(\n",
|
1004 |
-
" File \"/usr/local/lib/python3.9/site-packages/gradio/blocks.py\", line 1108, in process_api\n",
|
1005 |
-
" result = await self.call_function(\n",
|
1006 |
-
" File \"/usr/local/lib/python3.9/site-packages/gradio/blocks.py\", line 915, in call_function\n",
|
1007 |
-
" prediction = await anyio.to_thread.run_sync(\n",
|
1008 |
-
" File \"/usr/local/lib/python3.9/site-packages/anyio/to_thread.py\", line 31, in run_sync\n",
|
1009 |
-
" return await get_asynclib().run_sync_in_worker_thread(\n",
|
1010 |
-
" File \"/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 937, in run_sync_in_worker_thread\n",
|
1011 |
-
" return await future\n",
|
1012 |
-
" File \"/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 867, in run\n",
|
1013 |
-
" result = context.run(func, *args)\n",
|
1014 |
-
" File \"/var/folders/ky/4j6xbvhs5m583jflkhyzxf9h0000gn/T/ipykernel_9385/3876498698.py\", line 76, in mark_phases\n",
|
1015 |
-
" waveform = resample_waveform(waveform, sampling_rate, 100)\n",
|
1016 |
-
" File \"/var/folders/ky/4j6xbvhs5m583jflkhyzxf9h0000gn/T/ipykernel_9385/3876498698.py\", line 46, in resample_waveform\n",
|
1017 |
-
" resampled_length = int(waveform.shape[-1] * resampling_ratio)\n",
|
1018 |
-
"AttributeError: 'str' object has no attribute 'shape'\n"
|
1019 |
-
]
|
1020 |
}
|
1021 |
],
|
1022 |
"source": [
|
1023 |
-
"a = np.load(\"
|
1024 |
-
"
|
1025 |
-
"\n"
|
1026 |
-
"b = resample_waveform(a, 200, 100)\n",
|
1027 |
-
"plt.plot(b)"
|
1028 |
]
|
1029 |
},
|
1030 |
{
|
@@ -1038,102 +876,27 @@
|
|
1038 |
},
|
1039 |
{
|
1040 |
"cell_type": "code",
|
1041 |
-
"execution_count":
|
1042 |
"metadata": {},
|
1043 |
"outputs": [
|
1044 |
{
|
1045 |
-
"
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
" '__delattr__',\n",
|
1051 |
-
" '__dict__',\n",
|
1052 |
-
" '__dir__',\n",
|
1053 |
-
" '__doc__',\n",
|
1054 |
-
" '__eq__',\n",
|
1055 |
-
" '__format__',\n",
|
1056 |
-
" '__ge__',\n",
|
1057 |
-
" '__getattribute__',\n",
|
1058 |
-
" '__getstate__',\n",
|
1059 |
-
" '__gt__',\n",
|
1060 |
-
" '__hash__',\n",
|
1061 |
-
" '__init__',\n",
|
1062 |
-
" '__init_subclass__',\n",
|
1063 |
-
" '__le__',\n",
|
1064 |
-
" '__lt__',\n",
|
1065 |
-
" '__module__',\n",
|
1066 |
-
" '__ne__',\n",
|
1067 |
-
" '__new__',\n",
|
1068 |
-
" '__reduce__',\n",
|
1069 |
-
" '__reduce_ex__',\n",
|
1070 |
-
" '__repr__',\n",
|
1071 |
-
" '__setattr__',\n",
|
1072 |
-
" '__sizeof__',\n",
|
1073 |
-
" '__slots__',\n",
|
1074 |
-
" '__str__',\n",
|
1075 |
-
" '__subclasshook__',\n",
|
1076 |
-
" '__weakref__',\n",
|
1077 |
-
" '_abc_impl',\n",
|
1078 |
-
" '_id',\n",
|
1079 |
-
" '_skip_init_processing',\n",
|
1080 |
-
" '_style',\n",
|
1081 |
-
" 'as_example',\n",
|
1082 |
-
" 'attach_load_event',\n",
|
1083 |
-
" 'base64_to_temp_file_if_needed',\n",
|
1084 |
-
" 'change',\n",
|
1085 |
-
" 'clear',\n",
|
1086 |
-
" 'deserialize',\n",
|
1087 |
-
" 'download_temp_copy_if_needed',\n",
|
1088 |
-
" 'elem_classes',\n",
|
1089 |
-
" 'elem_id',\n",
|
1090 |
-
" 'file_count',\n",
|
1091 |
-
" 'file_types',\n",
|
1092 |
-
" 'get_block_name',\n",
|
1093 |
-
" 'get_config',\n",
|
1094 |
-
" 'get_expected_parent',\n",
|
1095 |
-
" 'get_load_fn_and_initial_value',\n",
|
1096 |
-
" 'get_specific_update',\n",
|
1097 |
-
" 'hash_base64',\n",
|
1098 |
-
" 'hash_file',\n",
|
1099 |
-
" 'hash_url',\n",
|
1100 |
-
" 'info',\n",
|
1101 |
-
" 'interactive',\n",
|
1102 |
-
" 'label',\n",
|
1103 |
-
" 'load_event',\n",
|
1104 |
-
" 'load_event_to_attach',\n",
|
1105 |
-
" 'make_temp_copy_if_needed',\n",
|
1106 |
-
" 'parent',\n",
|
1107 |
-
" 'postprocess',\n",
|
1108 |
-
" 'preprocess',\n",
|
1109 |
-
" 'render',\n",
|
1110 |
-
" 'root',\n",
|
1111 |
-
" 'root_url',\n",
|
1112 |
-
" 'save_uploaded_file',\n",
|
1113 |
-
" 'select',\n",
|
1114 |
-
" 'selectable',\n",
|
1115 |
-
" 'serialize',\n",
|
1116 |
-
" 'set_event_trigger',\n",
|
1117 |
-
" 'share_token',\n",
|
1118 |
-
" 'show_label',\n",
|
1119 |
-
" 'style',\n",
|
1120 |
-
" 'temp_files',\n",
|
1121 |
-
" 'test_input',\n",
|
1122 |
-
" 'type',\n",
|
1123 |
-
" 'unrender',\n",
|
1124 |
-
" 'update',\n",
|
1125 |
-
" 'upload',\n",
|
1126 |
-
" 'value',\n",
|
1127 |
-
" 'visible']"
|
1128 |
-
]
|
1129 |
-
},
|
1130 |
-
"execution_count": 2,
|
1131 |
-
"metadata": {},
|
1132 |
-
"output_type": "execute_result"
|
1133 |
}
|
1134 |
],
|
1135 |
"source": [
|
1136 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1137 |
]
|
1138 |
},
|
1139 |
{
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
+
"execution_count": 44,
|
6 |
"metadata": {},
|
7 |
"outputs": [
|
8 |
{
|
9 |
"name": "stdout",
|
10 |
"output_type": "stream",
|
11 |
"text": [
|
12 |
+
"Running on local URL: http://127.0.0.1:7872\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:7872/\" 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": 44,
|
34 |
"metadata": {},
|
35 |
"output_type": "execute_result"
|
36 |
},
|
|
|
38 |
"name": "stdout",
|
39 |
"output_type": "stream",
|
40 |
"text": [
|
41 |
+
"Loaded (1, 28412)\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
]
|
43 |
}
|
44 |
],
|
|
|
94 |
" \n",
|
95 |
" return resampled_waveform\n",
|
96 |
"\n",
|
97 |
+
"def sort_channels_to_ZNE(waveform, channels):\n",
|
98 |
+
" # Input:\n",
|
99 |
+
" # waveform: a 2D numpy array with shape (3, n), where n is the number of samples\n",
|
100 |
+
" # channels: a list or tuple of 3 strings representing the channel order, e.g. ('N', 'Z', 'E')\n",
|
101 |
+
" channels = list(channels)\n",
|
102 |
+
"\n",
|
103 |
+
" if len(channels) != 3 or set(channels) != {'Z', 'N', 'E'}:\n",
|
104 |
+
" raise ValueError(\"Invalid channel input. It should be a permutation of 'Z', 'N', and 'E'.\")\n",
|
105 |
+
"\n",
|
106 |
+
" # Find the indices of the Z, N, and E channels\n",
|
107 |
+
" z_index = channels.index('Z')\n",
|
108 |
+
" n_index = channels.index('N')\n",
|
109 |
+
" e_index = channels.index('E')\n",
|
110 |
+
" \n",
|
111 |
+
" print(z_index, n_index, e_index)\n",
|
112 |
+
" # Sort the channels to ZNE\n",
|
113 |
+
" sorted_waveform = waveform[[z_index, n_index, e_index], :]\n",
|
114 |
+
" \n",
|
115 |
+
" return sorted_waveform\n",
|
116 |
+
"\n",
|
117 |
+
"def make_prediction(waveform, sampling_rate, order):\n",
|
118 |
" waveform = np.load(waveform)\n",
|
119 |
" print('Loaded', waveform.shape)\n",
|
120 |
"\n",
|
121 |
" if len(waveform.shape) == 1:\n",
|
122 |
" waveform = waveform.reshape(1, waveform.shape[0])\n",
|
123 |
+
"\n",
|
124 |
+
" elif waveform.shape[0] == 3:\n",
|
125 |
+
" waveform = sort_channels_to_ZNE(waveform, order)\n",
|
126 |
+
"\n",
|
127 |
" if sampling_rate != 100:\n",
|
128 |
" waveform = resample_waveform(waveform, sampling_rate, 100)\n",
|
129 |
" print('Resampled', waveform.shape)\n",
|
130 |
"\n",
|
131 |
+
"\n",
|
132 |
" orig_waveform = waveform[:, :6000].copy()\n",
|
133 |
" processed_input = prepare_waveform(waveform)\n",
|
134 |
"\n",
|
|
|
142 |
" return processed_input, p_phase, s_phase, orig_waveform\n",
|
143 |
"\n",
|
144 |
"\n",
|
145 |
+
"def mark_phases(waveform, uploaded_file, p_thres, s_thres, sampling_rate, order):\n",
|
146 |
"\n",
|
147 |
" if uploaded_file is not None:\n",
|
148 |
" waveform = uploaded_file.name\n",
|
149 |
"\n",
|
150 |
+
" processed_input, p_phase, s_phase, orig_waveform = make_prediction(waveform, sampling_rate, order)\n",
|
151 |
"\n",
|
152 |
" # Create a plot of the waveform with the phases marked\n",
|
153 |
" if sum(processed_input[0][2] == 0): #if input is 1C\n",
|
|
|
322 |
" if len(waveforms) == 0:\n",
|
323 |
" print('No waveforms found')\n",
|
324 |
" fig, ax = plt.subplots()\n",
|
325 |
+
" # prints \"No waveforms found\" on the plot aligned at center and vertically\n",
|
326 |
+
" ax.text(0.5,0.5,'No waveforms found', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)\n",
|
327 |
" fig.canvas.draw();\n",
|
328 |
" image = np.array(fig.canvas.renderer.buffer_rgba())\n",
|
329 |
" plt.close(fig)\n",
|
330 |
+
"\n",
|
331 |
" output_picks = pd.DataFrame()\n",
|
332 |
" output_picks.to_csv('data/picks.csv', index=False)\n",
|
333 |
" output_csv = 'data/picks.csv'\n",
|
|
|
651 |
" info=\"Sampling rate of the waveform\",\n",
|
652 |
" interactive=True,\n",
|
653 |
" )\n",
|
654 |
+
" order_input = gr.Text(value='ZNE', \n",
|
655 |
+
" label='Channel order', \n",
|
656 |
+
" info='Order of the channels in the waveform file (e.g. ZNE)')\n",
|
657 |
"\n",
|
658 |
" button = gr.Button(\"Predict phases\")\n",
|
659 |
" outputs = gr.Image(label='Waveform with Phases Marked', type='numpy', interactive=False)\n",
|
660 |
" \n",
|
661 |
" button.click(mark_phases, inputs=[inputs, upload, \n",
|
662 |
" P_thres_inputs, S_thres_inputs,\n",
|
663 |
+
" sampling_rate_inputs, order_input], \n",
|
664 |
" outputs=outputs) \n",
|
665 |
" with gr.Tab(\"Select earthquake from catalogue\"):\n",
|
666 |
"\n",
|
|
|
792 |
},
|
793 |
{
|
794 |
"cell_type": "code",
|
795 |
+
"execution_count": 34,
|
796 |
+
"metadata": {},
|
797 |
+
"outputs": [
|
798 |
+
{
|
799 |
+
"data": {
|
800 |
+
"text/plain": [
|
801 |
+
"array([[53, 52, 28, ..., 0, 0, 0]], dtype=int32)"
|
802 |
+
]
|
803 |
+
},
|
804 |
+
"execution_count": 34,
|
805 |
+
"metadata": {},
|
806 |
+
"output_type": "execute_result"
|
807 |
+
},
|
808 |
+
{
|
809 |
+
"name": "stdout",
|
810 |
+
"output_type": "stream",
|
811 |
+
"text": [
|
812 |
+
"Loaded (1, 25412)\n",
|
813 |
+
"Reshaped (1, 25412)\n"
|
814 |
+
]
|
815 |
+
},
|
816 |
+
{
|
817 |
+
"name": "stderr",
|
818 |
+
"output_type": "stream",
|
819 |
+
"text": [
|
820 |
+
"No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.\n"
|
821 |
+
]
|
822 |
+
},
|
823 |
+
{
|
824 |
+
"name": "stdout",
|
825 |
+
"output_type": "stream",
|
826 |
+
"text": [
|
827 |
+
"Loaded (1, 25412)\n",
|
828 |
+
"Reshaped (1, 25412)\n"
|
829 |
+
]
|
830 |
+
}
|
831 |
+
],
|
832 |
+
"source": [
|
833 |
+
"np.load('test_no_p.npy')"
|
834 |
+
]
|
835 |
+
},
|
836 |
+
{
|
837 |
+
"cell_type": "code",
|
838 |
+
"execution_count": 33,
|
839 |
"metadata": {},
|
840 |
"outputs": [
|
841 |
{
|
842 |
"data": {
|
843 |
"text/plain": [
|
844 |
+
"[<matplotlib.lines.Line2D at 0x1ccb9acd0>]"
|
845 |
]
|
846 |
},
|
847 |
+
"execution_count": 33,
|
848 |
"metadata": {},
|
849 |
"output_type": "execute_result"
|
850 |
},
|
851 |
{
|
852 |
"data": {
|
853 |
+
"image/png": "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9+61HnfccYc1LxgMavTo0erRo4cKCgr08MMPa+7cuXrmmWesNitWrNCNN96oSZMmafXq1Ro/frzGjx+vdevW2bE5OA0MWgYARIrtp6V37NhRKSkpjc574YUXVFNTo2effVYej0cDBgxQYWGhHnnkEU2ePFmS9Nhjj2nMmDGaMWOGJOnBBx9Ubm6unnjiCT399NMR2w4AANBy2b6HZ/78+erSpYuGDh2qhx9+WHV1dda8/Px8jRw5Uh6Px3ouOztbmzdv1sGDB602WVlZIcvMzs5Wfn5+ZDYAAAC0eLbu4fmP//gPXXjhhercubNWrFihWbNmae/evXrkkUckSYFAQL169Qp5TXJysjWvU6dOCgQC1nPfbhMIBE643urqalVXV1vTwWCwuTYJp4HT0gEAkdLse3hmzpx53EDk7z42bdokScrJydGoUaM0ePBg3X777frTn/6kxx9/PCSMhMO8efPk9/utR1paWljXBwAA7NXse3juuusu3XLLLSdt07t370afz8jIUF1dnXbs2KH09HSlpKSouLg4pM2x6WPjfk7U5kTjgiRp1qxZysnJsaaDwSChxwYMWgYAREqzB57ExEQlJiae0WsLCwvldruVlJQkScrMzNR9992n2tpaxcTESJJyc3OVnp6uTp06WW3y8vI0ffp0azm5ubnKzMw84Xq8Xq+8Xu8Z1QgAAFof2wYt5+fn69FHH9WaNWv01Vdf6YUXXtCdd96pn/70p1aYuemmm+TxeDRp0iStX79eL7/8sh577LGQvTO//OUvtXjxYv3pT3/Spk2bNHfuXK1atUrTpk2za9MAAEALY9ugZa/Xq5deeklz585VdXW1evXqpTvvvDMkzPj9fr333nuaOnWqhg0bpoSEBM2ePds6JV2SLrvsMv3973/X/fffr1/96lc699xztWjRIg0cONCOzQIAAC2QyxjOlQkGg/L7/SovL5fP57O7nFar58y3Tqv9xT076dXbLwtTNQAApzud32/br8MDAAAQbgQeAADgeAQeAADgeAQe2CbF387uEgAAbQSBB7YYOzBFs3/U3+4yAABthO13S0fb9NRPh9ldAgCgDWEPDwAAcDwCD5oN98YCALRUBB40m8/uyzrp/BnZ6RGqBACAUAQeNJuEDie/IWviKeYDABAuBB4AAOB4BB4AAOB4BB5EjFGbv08tAMAmBB4AAOB4BB4AAOB4BB5ETKc4j90lAADaKG4tgYjJOj9ZEzN7aEhavN2lAADaGAIPIsbtduk31wy0uwwAQBvEIS0AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB4AAOB4BB40q/aeKLtLAADgOAQeNKt+XX12lwAAwHEIPAAAwPEIPAAAwPEIPAAAwPEIPAAAwPEIPAAAwPEIPAAAwPEIPAAAwPEIPAAAwPGi7S4Aznbt0G7yt4vR+KHd7C4FANCGEXgQVr7YaM29eoDdZQAA2jgOaQEAAMcj8AAAAMcj8CCsRqUn2V0CAAAEHoTXqPREu0sAAIDAg+Z1+/f7WH8P7R4vl8tlYzUAABxF4EGz+mH/ZLtLAADgOAQeAADgeAQeAADgeAQeAADgeAQeAADgeAQeAADgeAQeAADgeGELPL/73e902WWXKS4uTvHx8Y22KSoq0rhx4xQXF6ekpCTNmDFDdXV1IW2WLVumCy+8UF6vV3379tXChQuPW86CBQvUs2dPxcbGKiMjQ59++mkYtggAALRWYQs8NTU1+slPfqIpU6Y0Or++vl7jxo1TTU2NVqxYoeeff14LFy7U7NmzrTbbt2/XuHHjdPnll6uwsFDTp0/Xz3/+c7377rtWm5dfflk5OTmaM2eOPv/8cw0ZMkTZ2dkqKSkJ16YBAIBWxmWMMeFcwcKFCzV9+nSVlZWFPP/OO+/oRz/6kfbs2aPk5KMXq3v66ad17733at++ffJ4PLr33nv11ltvad26ddbrbrjhBpWVlWnx4sWSpIyMDF188cV64oknJEkNDQ1KS0vTHXfcoZkzZzapxmAwKL/fr/Lycvl8vmbY6rat58y3JEkXdo/Xa7/4ns3VAACc6nR+v20bw5Ofn69BgwZZYUeSsrOzFQwGtX79eqtNVlZWyOuys7OVn58v6ehepIKCgpA2brdbWVlZVpvGVFdXKxgMhjwAAIBz2RZ4AoFASNiRZE0HAoGTtgkGgzpy5Ij279+v+vr6RtscW0Zj5s2bJ7/fbz3S0tKaY5MAAEALdVqBZ+bMmXK5XCd9bNq0KVy1NptZs2apvLzceuzcudPukgAAQBhFn07ju+66S7fccstJ2/Tu3btJy0pJSTnubKri4mJr3rH/Hnvu2218Pp/atWunqKgoRUVFNdrm2DIa4/V65fV6m1QnAABo/U4r8CQmJioxMbFZVpyZmanf/e53KikpUVJSkiQpNzdXPp9P/fv3t9q8/fbbIa/Lzc1VZmamJMnj8WjYsGHKy8vT+PHjJR0dtJyXl6dp06Y1S504cy6Xy+4SAACQFMYxPEVFRSosLFRRUZHq6+tVWFiowsJCVVZWSpJGjx6t/v376+abb9aaNWv07rvv6v7779fUqVOtvS+33367vvrqK91zzz3atGmTnnzySb3yyiu68847rfXk5OToP//zP/X8889r48aNmjJlig4dOqRbb701XJuGJgrzCYAAADTZae3hOR2zZ8/W888/b00PHTpUkrR06VKNGjVKUVFRevPNNzVlyhRlZmaqffv2mjhxoh544AHrNb169dJbb72lO++8U4899pjOOecc/dd//Zeys7OtNtdff7327dun2bNnKxAI6IILLtDixYuPG8gMAADarrBfh6c14Do8zYvr8AAAIqFVXIcHAAAgUgg8CBsGLQMAWgoCDwAAcDwCDwAAcDwCDwAAcDwCDwAAcDwCD8KGIcsAgJaCwAMAAByPwAMAAByPwIOwafOX8AYAtBgEHgAA4HgEHoQNg5YBAC0FgQcAADgegQcAADgegQcAADgegQcAADgegQdh42LUMgCghSDwAAAAxyPwAAAAxyPwAAAAxyPwoNlFu48O3sns3cXmSgAAOCra7gLgPEvvHqUPvtynn1x0jt2lAAAgicCDMEjrHKefXtrD7jIAALBwSAsAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADgegQcAADged0uXZIyRJAWDQZsrAQAATXXsd/vY7/jJEHgkVVRUSJLS0tJsrgQAAJyuiooK+f3+k7ZxmabEIodraGjQnj171LFjR7lcrmZddjAYVFpamnbu3Cmfz9esy3Y6+u7s0H9njr47c/Td2aH/To8xRhUVFUpNTZXbffJROuzhkeR2u3XOOeeEdR0+n4837xmi784O/Xfm6LszR9+dHfqv6U61Z+cYBi0DAADHI/AAAADHI/CEmdfr1Zw5c+T1eu0updWh784O/Xfm6LszR9+dHfovfBi0DAAAHI89PAAAwPEIPAAAwPEIPAAAwPEIPAAAwPEIPGG2YMEC9ezZU7GxscrIyNCnn35qd0kRNXfuXLlcrpBHv379rPlVVVWaOnWqunTpog4dOui6665TcXFxyDKKioo0btw4xcXFKSkpSTNmzFBdXV1Im2XLlunCCy+U1+tV3759tXDhwkhsXrNavny5rrrqKqWmpsrlcmnRokUh840xmj17trp27ap27dopKytLW7ZsCWlTWlqqCRMmyOfzKT4+XpMmTVJlZWVIm7Vr12rEiBGKjY1VWlqaHnrooeNqefXVV9WvXz/FxsZq0KBBevvtt5t9e5vbqfrvlltuOe69OGbMmJA2bbX/5s2bp4svvlgdO3ZUUlKSxo8fr82bN4e0ieRntTV9bzal70aNGnXce+/2228PadMW+y7iDMLmpZdeMh6Pxzz77LNm/fr15rbbbjPx8fGmuLjY7tIiZs6cOWbAgAFm79691mPfvn3W/Ntvv92kpaWZvLw8s2rVKnPppZeayy67zJpfV1dnBg4caLKysszq1avN22+/bRISEsysWbOsNl999ZWJi4szOTk5ZsOGDebxxx83UVFRZvHixRHd1rP19ttvm/vuu8+89tprRpJ5/fXXQ+bPnz/f+P1+s2jRIrNmzRpz9dVXm169epkjR45YbcaMGWOGDBliPvnkE/Phhx+avn37mhtvvNGaX15ebpKTk82ECRPMunXrzIsvvmjatWtn/vrXv1ptPv74YxMVFWUeeughs2HDBnP//febmJgY88UXX4S9D87Gqfpv4sSJZsyYMSHvxdLS0pA2bbX/srOzzXPPPWfWrVtnCgsLzZVXXmm6d+9uKisrrTaR+qy2tu/NpvTd97//fXPbbbeFvPfKy8ut+W217yKNwBNGl1xyiZk6dao1XV9fb1JTU828efNsrCqy5syZY4YMGdLovLKyMhMTE2NeffVV67mNGzcaSSY/P98Yc/RHzO12m0AgYLV56qmnjM/nM9XV1cYYY+655x4zYMCAkGVff/31Jjs7u5m3JnK++4Pd0NBgUlJSzMMPP2w9V1ZWZrxer3nxxReNMcZs2LDBSDKfffaZ1eadd94xLpfL7N692xhjzJNPPmk6depk9Z0xxtx7770mPT3dmv63f/s3M27cuJB6MjIyzL//+7836zaG04kCzzXXXHPC19B/3ygpKTGSzAcffGCMiexntbV/b36374w5Gnh++ctfnvA19F1kcEgrTGpqalRQUKCsrCzrObfbraysLOXn59tYWeRt2bJFqamp6t27tyZMmKCioiJJUkFBgWpra0P6qF+/furevbvVR/n5+Ro0aJCSk5OtNtnZ2QoGg1q/fr3V5tvLONbGSf28fft2BQKBkO30+/3KyMgI6av4+HhddNFFVpusrCy53W6tXLnSajNy5Eh5PB6rTXZ2tjZv3qyDBw9abZzan8uWLVNSUpLS09M1ZcoUHThwwJpH/32jvLxcktS5c2dJkfusOuF787t9d8wLL7yghIQEDRw4ULNmzdLhw4etefRdZHDz0DDZv3+/6uvrQ97AkpScnKxNmzbZVFXkZWRkaOHChUpPT9fevXv1m9/8RiNGjNC6desUCATk8XgUHx8f8prk5GQFAgFJUiAQaLQPj807WZtgMKgjR46oXbt2Ydq6yDm2rY1t57f7ISkpKWR+dHS0OnfuHNKmV69exy3j2LxOnTqdsD+PLaO1GjNmjH784x+rV69e2rZtm371q19p7Nixys/PV1RUFP33Lw0NDZo+fbq+973vaeDAgZIUsc/qwYMHW/X3ZmN9J0k33XSTevToodTUVK1du1b33nuvNm/erNdee00SfRcpBB6E1dixY62/Bw8erIyMDPXo0UOvvPKKI4IIWo8bbrjB+nvQoEEaPHiw+vTpo2XLlumKK66wsbKWZerUqVq3bp0++ugju0tpdU7Ud5MnT7b+HjRokLp27aorrrhC27ZtU58+fSJdZpvFIa0wSUhIUFRU1HFnMRQXFyslJcWmquwXHx+v8847T1u3blVKSopqampUVlYW0ubbfZSSktJoHx6bd7I2Pp/PMaHq2Lae7P2UkpKikpKSkPl1dXUqLS1tlv502vu2d+/eSkhI0NatWyXRf5I0bdo0vfnmm1q6dKnOOecc6/lIfVZb8/fmifquMRkZGZIU8t5ry30XKQSeMPF4PBo2bJjy8vKs5xoaGpSXl6fMzEwbK7NXZWWltm3bpq5du2rYsGGKiYkJ6aPNmzerqKjI6qPMzEx98cUXIT9Eubm58vl86t+/v9Xm28s41sZJ/dyrVy+lpKSEbGcwGNTKlStD+qqsrEwFBQVWmyVLlqihocH6gs3MzNTy5ctVW1trtcnNzVV6ero6depktXF6f0rSrl27dODAAXXt2lVS2+4/Y4ymTZum119/XUuWLDnusF2kPqut8XvzVH3XmMLCQkkKee+1xb6LOLtHTTvZSy+9ZLxer1m4cKHZsGGDmTx5somPjw8Zie90d911l1m2bJnZvn27+fjjj01WVpZJSEgwJSUlxpijp7p2797dLFmyxKxatcpkZmaazMxM6/XHTtccPXq0KSwsNIsXLzaJiYmNnq45Y8YMs3HjRrNgwYJWeVp6RUWFWb16tVm9erWRZB555BGzevVq8/XXXxtjjp6WHh8fb9544w2zdu1ac8011zR6WvrQoUPNypUrzUcffWTOPffckNOqy8rKTHJysrn55pvNunXrzEsvvWTi4uKOO606Ojra/PGPfzQbN240c+bMafGnVRtz8v6rqKgwd999t8nPzzfbt28377//vrnwwgvNueeea6qqqqxltNX+mzJlivH7/WbZsmUhp04fPnzYahOpz2pr+948Vd9t3brVPPDAA2bVqlVm+/bt5o033jC9e/c2I0eOtJbRVvsu0gg8Yfb444+b7t27G4/HYy655BLzySef2F1SRF1//fWma9euxuPxmG7dupnrr7/ebN261Zp/5MgR84tf/MJ06tTJxMXFmWuvvdbs3bs3ZBk7duwwY8eONe3atTMJCQnmrrvuMrW1tSFtli5dai644ALj8XhM7969zXPPPReJzWtWS5cuNZKOe0ycONEYc/TU9F//+tcmOTnZeL1ec8UVV5jNmzeHLOPAgQPmxhtvNB06dDA+n8/ceuutpqKiIqTNmjVrzPDhw43X6zXdunUz8+fPP66WV155xZx33nnG4/GYAQMGmLfeeits291cTtZ/hw8fNqNHjzaJiYkmJibG9OjRw9x2223H/RC01f5rrN8khXyOIvlZbU3fm6fqu6KiIjNy5EjTuXNn4/V6Td++fc2MGTNCrsNjTNvsu0hzGWNM5PYnAQAARB5jeAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOMReAAAgOP9/yWvYymBlXynAAAAAElFTkSuQmCC",
|
854 |
"text/plain": [
|
855 |
"<Figure size 640x480 with 1 Axes>"
|
856 |
]
|
857 |
},
|
858 |
"metadata": {},
|
859 |
"output_type": "display_data"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
}
|
861 |
],
|
862 |
"source": [
|
863 |
+
"a = np.load(\"data/sample/sample_1.npy\") \n",
|
864 |
+
"np.save('test_no_p.npy', a[:, 3000:])\n",
|
865 |
+
"plt.plot(a[0])\n"
|
|
|
|
|
866 |
]
|
867 |
},
|
868 |
{
|
|
|
876 |
},
|
877 |
{
|
878 |
"cell_type": "code",
|
879 |
+
"execution_count": 37,
|
880 |
"metadata": {},
|
881 |
"outputs": [
|
882 |
{
|
883 |
+
"name": "stdout",
|
884 |
+
"output_type": "stream",
|
885 |
+
"text": [
|
886 |
+
"1 0 2\n"
|
887 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
888 |
}
|
889 |
],
|
890 |
"source": [
|
891 |
+
"import numpy as np\n",
|
892 |
+
"\n",
|
893 |
+
"\n",
|
894 |
+
"\n",
|
895 |
+
"# Example usage:\n",
|
896 |
+
"waveform = np.random.rand(3, 100) # A random waveform with 3 channels and 100 samples\n",
|
897 |
+
"channels = 'NZE'\n",
|
898 |
+
"\n",
|
899 |
+
"sorted_waveform = sort_channels_to_ZNE(waveform, channels)"
|
900 |
]
|
901 |
},
|
902 |
{
|
app.py
CHANGED
@@ -49,17 +49,41 @@ def resample_waveform(waveform, original_freq, target_freq):
|
|
49 |
|
50 |
return resampled_waveform
|
51 |
|
52 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
waveform = np.load(waveform)
|
54 |
print('Loaded', waveform.shape)
|
55 |
|
56 |
if len(waveform.shape) == 1:
|
57 |
waveform = waveform.reshape(1, waveform.shape[0])
|
58 |
-
|
|
|
|
|
|
|
59 |
if sampling_rate != 100:
|
60 |
waveform = resample_waveform(waveform, sampling_rate, 100)
|
61 |
print('Resampled', waveform.shape)
|
62 |
|
|
|
63 |
orig_waveform = waveform[:, :6000].copy()
|
64 |
processed_input = prepare_waveform(waveform)
|
65 |
|
@@ -73,12 +97,12 @@ def make_prediction(waveform, sampling_rate):
|
|
73 |
return processed_input, p_phase, s_phase, orig_waveform
|
74 |
|
75 |
|
76 |
-
def mark_phases(waveform, uploaded_file, p_thres, s_thres, sampling_rate):
|
77 |
|
78 |
if uploaded_file is not None:
|
79 |
waveform = uploaded_file.name
|
80 |
|
81 |
-
processed_input, p_phase, s_phase, orig_waveform = make_prediction(waveform, sampling_rate)
|
82 |
|
83 |
# Create a plot of the waveform with the phases marked
|
84 |
if sum(processed_input[0][2] == 0): #if input is 1C
|
@@ -253,10 +277,12 @@ def predict_on_section(client_name, timestamp, eq_lat, eq_lon, radius_km, source
|
|
253 |
if len(waveforms) == 0:
|
254 |
print('No waveforms found')
|
255 |
fig, ax = plt.subplots()
|
256 |
-
|
|
|
257 |
fig.canvas.draw();
|
258 |
image = np.array(fig.canvas.renderer.buffer_rgba())
|
259 |
plt.close(fig)
|
|
|
260 |
output_picks = pd.DataFrame()
|
261 |
output_picks.to_csv('data/picks.csv', index=False)
|
262 |
output_csv = 'data/picks.csv'
|
@@ -580,13 +606,16 @@ with gr.Blocks() as demo:
|
|
580 |
info="Sampling rate of the waveform",
|
581 |
interactive=True,
|
582 |
)
|
|
|
|
|
|
|
583 |
|
584 |
button = gr.Button("Predict phases")
|
585 |
outputs = gr.Image(label='Waveform with Phases Marked', type='numpy', interactive=False)
|
586 |
|
587 |
button.click(mark_phases, inputs=[inputs, upload,
|
588 |
P_thres_inputs, S_thres_inputs,
|
589 |
-
sampling_rate_inputs],
|
590 |
outputs=outputs)
|
591 |
with gr.Tab("Select earthquake from catalogue"):
|
592 |
|
|
|
49 |
|
50 |
return resampled_waveform
|
51 |
|
52 |
+
def sort_channels_to_ZNE(waveform, channels):
|
53 |
+
# Input:
|
54 |
+
# waveform: a 2D numpy array with shape (3, n), where n is the number of samples
|
55 |
+
# channels: a list or tuple of 3 strings representing the channel order, e.g. ('N', 'Z', 'E')
|
56 |
+
channels = list(channels)
|
57 |
+
|
58 |
+
if len(channels) != 3 or set(channels) != {'Z', 'N', 'E'}:
|
59 |
+
raise ValueError("Invalid channel input. It should be a permutation of 'Z', 'N', and 'E'.")
|
60 |
+
|
61 |
+
# Find the indices of the Z, N, and E channels
|
62 |
+
z_index = channels.index('Z')
|
63 |
+
n_index = channels.index('N')
|
64 |
+
e_index = channels.index('E')
|
65 |
+
|
66 |
+
print(z_index, n_index, e_index)
|
67 |
+
# Sort the channels to ZNE
|
68 |
+
sorted_waveform = waveform[[z_index, n_index, e_index], :]
|
69 |
+
|
70 |
+
return sorted_waveform
|
71 |
+
|
72 |
+
def make_prediction(waveform, sampling_rate, order):
|
73 |
waveform = np.load(waveform)
|
74 |
print('Loaded', waveform.shape)
|
75 |
|
76 |
if len(waveform.shape) == 1:
|
77 |
waveform = waveform.reshape(1, waveform.shape[0])
|
78 |
+
|
79 |
+
elif waveform.shape[0] == 3:
|
80 |
+
waveform = sort_channels_to_ZNE(waveform, order)
|
81 |
+
|
82 |
if sampling_rate != 100:
|
83 |
waveform = resample_waveform(waveform, sampling_rate, 100)
|
84 |
print('Resampled', waveform.shape)
|
85 |
|
86 |
+
|
87 |
orig_waveform = waveform[:, :6000].copy()
|
88 |
processed_input = prepare_waveform(waveform)
|
89 |
|
|
|
97 |
return processed_input, p_phase, s_phase, orig_waveform
|
98 |
|
99 |
|
100 |
+
def mark_phases(waveform, uploaded_file, p_thres, s_thres, sampling_rate, order):
|
101 |
|
102 |
if uploaded_file is not None:
|
103 |
waveform = uploaded_file.name
|
104 |
|
105 |
+
processed_input, p_phase, s_phase, orig_waveform = make_prediction(waveform, sampling_rate, order)
|
106 |
|
107 |
# Create a plot of the waveform with the phases marked
|
108 |
if sum(processed_input[0][2] == 0): #if input is 1C
|
|
|
277 |
if len(waveforms) == 0:
|
278 |
print('No waveforms found')
|
279 |
fig, ax = plt.subplots()
|
280 |
+
# prints "No waveforms found" on the plot aligned at center and vertically
|
281 |
+
ax.text(0.5,0.5,'No waveforms found', horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
|
282 |
fig.canvas.draw();
|
283 |
image = np.array(fig.canvas.renderer.buffer_rgba())
|
284 |
plt.close(fig)
|
285 |
+
|
286 |
output_picks = pd.DataFrame()
|
287 |
output_picks.to_csv('data/picks.csv', index=False)
|
288 |
output_csv = 'data/picks.csv'
|
|
|
606 |
info="Sampling rate of the waveform",
|
607 |
interactive=True,
|
608 |
)
|
609 |
+
order_input = gr.Text(value='ZNE',
|
610 |
+
label='Channel order',
|
611 |
+
info='Order of the channels in the waveform file (e.g. ZNE)')
|
612 |
|
613 |
button = gr.Button("Predict phases")
|
614 |
outputs = gr.Image(label='Waveform with Phases Marked', type='numpy', interactive=False)
|
615 |
|
616 |
button.click(mark_phases, inputs=[inputs, upload,
|
617 |
P_thres_inputs, S_thres_inputs,
|
618 |
+
sampling_rate_inputs, order_input],
|
619 |
outputs=outputs)
|
620 |
with gr.Tab("Select earthquake from catalogue"):
|
621 |
|
data/cached/AK_CAPN_2023-04-10T17:33:40.015179Z.mseed
ADDED
Binary file (44.5 kB). View file
|
|
data/cached/AV_KENI_2023-04-10T17:33:41.392981Z.mseed
ADDED
Binary file (43 kB). View file
|
|
data/cached/CI_SLA_2023-04-10T17:33:40.190746Z.mseed
ADDED
Binary file (62 kB). View file
|
|
data/cached/GS_CA09_2023-04-10T17:33:38.249774Z.mseed
ADDED
Binary file (28.2 kB). View file
|
|
data/cached/PB_B916_2023-04-10T17:33:42.213172Z.mseed
ADDED
Binary file (26.6 kB). View file
|
|
data/cached/PB_B917_2023-04-10T17:33:42.616354Z.mseed
ADDED
Binary file (13.8 kB). View file
|
|
data/cached/PB_B921_2023-04-10T17:33:39.103517Z.mseed
ADDED
Binary file (13.8 kB). View file
|
|
data/picks.csv
CHANGED
@@ -1,4 +1 @@
|
|
1 |
-
|
2 |
-
CI.SRT,2019-07-04T17:33:38.029990Z,5.195954322814941,0.4883878491818905,11.277575492858887,1.6350263357162476,2.9791118172972846,1.3725759526093728
|
3 |
-
CI.JRC2,2019-07-04T17:33:39.947494Z,7.11562442779541,0.4898720048367977,13.208794593811035,1.644418090581894,4.255539668245224,2.29247429065224
|
4 |
-
CI.WMF,2019-07-04T17:33:41.867962Z,9.043024063110352,0.4864034615457058,15.146604537963867,1.6339519992470741,4.987844305676596,2.9779080827144124
|
|
|
1 |
+
|
|
|
|
|
|
test_no_p.npy
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:02e7a0fb5c2125a130b63c6de3e20a5349228fbc47eb4298ff41f42daef708d8
|
3 |
+
size 101776
|