update
Browse files- .gitattributes +6 -0
- Dockerfile +14 -22
- example_fastapi.ipynb +0 -0
- phasenet/app.py +17 -134
.gitattributes
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
model/190703-214543/loss.log filter=lfs diff=lfs merge=lfs -text
|
2 |
+
model/190703-214543/model_95.ckpt.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
|
3 |
+
model/190703-214543/model_95.ckpt.index filter=lfs diff=lfs merge=lfs -text
|
4 |
+
model/190703-214543/model_95.ckpt.meta filter=lfs diff=lfs merge=lfs -text
|
5 |
+
model/190703-214543/checkpoint filter=lfs diff=lfs merge=lfs -text
|
6 |
+
model/190703-214543/config.log filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
CHANGED
@@ -1,28 +1,20 @@
|
|
1 |
-
FROM
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
# Make RUN commands use the new environment:
|
7 |
-
# SHELL ["conda", "run", "-n", "cs329s", "/bin/bash", "-c"]
|
8 |
|
9 |
-
|
10 |
-
RUN pip install uvicorn fastapi kafka-python
|
11 |
|
12 |
-
|
|
|
13 |
|
14 |
-
#
|
|
|
|
|
15 |
|
16 |
-
#
|
17 |
-
COPY phasenet /opt/phasenet
|
18 |
-
# COPY model /opt/model
|
19 |
-
RUN wget https://github.com/AI4EPS/models/releases/download/PhaseNet-2018/model.tar && tar -xvf model.tar && rm model.tar
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
ENV PYTHONUNBUFFERED=1
|
25 |
-
|
26 |
-
# Start API server
|
27 |
-
#ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "cs329s", "uvicorn", "--app-dir", "phasenet", "app:app", "--reload", "--port", "8000", "--host", "0.0.0.0"]
|
28 |
-
ENTRYPOINT ["uvicorn", "--app-dir", "phasenet", "app:app", "--reload", "--port", "7860", "--host", "0.0.0.0"]
|
|
|
1 |
+
FROM python:3.9
|
2 |
|
3 |
+
RUN useradd -m -u 1000 user
|
4 |
+
USER user
|
5 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
|
|
|
|
6 |
|
7 |
+
WORKDIR /app
|
|
|
8 |
|
9 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
10 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
11 |
|
12 |
+
# COPY phasenet /app/phasenet
|
13 |
+
# COPY model /app/model
|
14 |
+
# RUN wget https://github.com/AI4EPS/models/releases/download/PhaseNet-2018/model.tar && tar -xvf model.tar && rm model.tar
|
15 |
|
16 |
+
# EXPOSE 80
|
|
|
|
|
|
|
17 |
|
18 |
+
RUN git lfs pull
|
19 |
+
COPY --chown=user . /app
|
20 |
+
ENTRYPOINT ["uvicorn", "--app-dir", "phasenet", "app:app", "--reload","--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
|
|
|
|
|
|
example_fastapi.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
phasenet/app.py
CHANGED
@@ -1,23 +1,21 @@
|
|
1 |
import os
|
2 |
-
from collections import defaultdict
|
3 |
from datetime import datetime, timedelta
|
4 |
-
from
|
5 |
-
from typing import Any, AnyStr, Dict, List, NamedTuple, Union, Optional
|
6 |
|
7 |
import numpy as np
|
8 |
-
import requests
|
9 |
import tensorflow as tf
|
10 |
from fastapi import FastAPI, WebSocket
|
11 |
-
from
|
12 |
from pydantic import BaseModel
|
13 |
from scipy.interpolate import interp1d
|
14 |
|
15 |
-
from model import
|
16 |
-
|
|
|
17 |
|
18 |
tf.compat.v1.disable_eager_execution()
|
19 |
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
|
20 |
-
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
|
21 |
JSONObject = Dict[AnyStr, Any]
|
22 |
JSONArray = List[Any]
|
23 |
JSONStructure = Union[JSONArray, JSONObject]
|
@@ -39,41 +37,6 @@ latest_check_point = tf.train.latest_checkpoint(f"{PROJECT_ROOT}/model/190703-21
|
|
39 |
print(f"restoring model {latest_check_point}")
|
40 |
saver.restore(sess, latest_check_point)
|
41 |
|
42 |
-
# GAMMA API Endpoint
|
43 |
-
GAMMA_API_URL = "http://gamma-api:8001"
|
44 |
-
# GAMMA_API_URL = 'http://localhost:8001'
|
45 |
-
# GAMMA_API_URL = "http://gamma.quakeflow.com"
|
46 |
-
# GAMMA_API_URL = "http://127.0.0.1:8001"
|
47 |
-
|
48 |
-
# Kafak producer
|
49 |
-
use_kafka = False
|
50 |
-
|
51 |
-
try:
|
52 |
-
print("Connecting to k8s kafka")
|
53 |
-
BROKER_URL = "quakeflow-kafka-headless:9092"
|
54 |
-
# BROKER_URL = "34.83.137.139:9094"
|
55 |
-
producer = KafkaProducer(
|
56 |
-
bootstrap_servers=[BROKER_URL],
|
57 |
-
key_serializer=lambda x: dumps(x).encode("utf-8"),
|
58 |
-
value_serializer=lambda x: dumps(x).encode("utf-8"),
|
59 |
-
)
|
60 |
-
use_kafka = True
|
61 |
-
print("k8s kafka connection success!")
|
62 |
-
except BaseException:
|
63 |
-
print("k8s Kafka connection error")
|
64 |
-
try:
|
65 |
-
print("Connecting to local kafka")
|
66 |
-
producer = KafkaProducer(
|
67 |
-
bootstrap_servers=["localhost:9092"],
|
68 |
-
key_serializer=lambda x: dumps(x).encode("utf-8"),
|
69 |
-
value_serializer=lambda x: dumps(x).encode("utf-8"),
|
70 |
-
)
|
71 |
-
use_kafka = True
|
72 |
-
print("local kafka connection success!")
|
73 |
-
except BaseException:
|
74 |
-
print("local Kafka connection error")
|
75 |
-
print(f"Kafka status: {use_kafka}")
|
76 |
-
|
77 |
|
78 |
def normalize_batch(data, window=3000):
|
79 |
"""
|
@@ -208,10 +171,7 @@ def get_prediction(data, return_preds=False):
|
|
208 |
|
209 |
|
210 |
class Data(BaseModel):
|
211 |
-
|
212 |
-
# timestamp: Union[List[str], str]
|
213 |
-
# vec: Union[List[List[List[float]]], List[List[float]]]
|
214 |
-
id: List[str]
|
215 |
timestamp: List[Union[str, float, datetime]]
|
216 |
vec: Union[List[List[List[float]]], List[List[float]]]
|
217 |
|
@@ -239,6 +199,13 @@ def predict(data: Data):
|
|
239 |
return picks
|
240 |
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
@app.websocket("/ws")
|
243 |
async def websocket_endpoint(websocket: WebSocket):
|
244 |
await websocket.accept()
|
@@ -251,95 +218,11 @@ async def websocket_endpoint(websocket: WebSocket):
|
|
251 |
print("PhaseNet Updating...")
|
252 |
|
253 |
|
254 |
-
@app.post("/predict_prob")
|
255 |
-
def predict(data: Data):
|
256 |
-
picks, preds = get_prediction(data, True)
|
257 |
-
|
258 |
-
return picks, preds.tolist()
|
259 |
-
|
260 |
-
|
261 |
-
@app.post("/predict_phasenet2gamma")
|
262 |
-
def predict(data: Data):
|
263 |
-
picks = get_prediction(data)
|
264 |
-
|
265 |
-
# if use_kafka:
|
266 |
-
# print("Push picks to kafka...")
|
267 |
-
# for pick in picks:
|
268 |
-
# producer.send("phasenet_picks", key=pick["id"], value=pick)
|
269 |
-
try:
|
270 |
-
catalog = requests.post(
|
271 |
-
f"{GAMMA_API_URL}/predict", json={"picks": picks, "stations": data.stations, "config": data.config}
|
272 |
-
)
|
273 |
-
print(catalog.json()["catalog"])
|
274 |
-
return catalog.json()
|
275 |
-
except Exception as error:
|
276 |
-
print(error)
|
277 |
-
|
278 |
-
return {}
|
279 |
-
|
280 |
-
|
281 |
-
@app.post("/predict_phasenet2gamma2ui")
|
282 |
-
def predict(data: Data):
|
283 |
-
picks = get_prediction(data)
|
284 |
-
|
285 |
-
try:
|
286 |
-
catalog = requests.post(
|
287 |
-
f"{GAMMA_API_URL}/predict", json={"picks": picks, "stations": data.stations, "config": data.config}
|
288 |
-
)
|
289 |
-
print(catalog.json()["catalog"])
|
290 |
-
return catalog.json()
|
291 |
-
except Exception as error:
|
292 |
-
print(error)
|
293 |
-
|
294 |
-
if use_kafka:
|
295 |
-
print("Push picks to kafka...")
|
296 |
-
for pick in picks:
|
297 |
-
producer.send("phasenet_picks", key=pick["id"], value=pick)
|
298 |
-
print("Push waveform to kafka...")
|
299 |
-
for id, timestamp, vec in zip(data.id, data.timestamp, data.vec):
|
300 |
-
producer.send("waveform_phasenet", key=id, value={"timestamp": timestamp, "vec": vec, "dt": data.dt})
|
301 |
-
|
302 |
-
return {}
|
303 |
-
|
304 |
-
|
305 |
-
@app.post("/predict_stream_phasenet2gamma")
|
306 |
-
def predict(data: Data):
|
307 |
-
data = format_data(data)
|
308 |
-
# for i in range(len(data.id)):
|
309 |
-
# plt.clf()
|
310 |
-
# plt.subplot(311)
|
311 |
-
# plt.plot(np.array(data.vec)[i, :, 0])
|
312 |
-
# plt.subplot(312)
|
313 |
-
# plt.plot(np.array(data.vec)[i, :, 1])
|
314 |
-
# plt.subplot(313)
|
315 |
-
# plt.plot(np.array(data.vec)[i, :, 2])
|
316 |
-
# plt.savefig(f"{data.id[i]}.png")
|
317 |
-
|
318 |
-
picks = get_prediction(data)
|
319 |
-
|
320 |
-
return_value = {}
|
321 |
-
try:
|
322 |
-
catalog = requests.post(f"{GAMMA_API_URL}/predict_stream", json={"picks": picks})
|
323 |
-
print("GMMA:", catalog.json()["catalog"])
|
324 |
-
return_value = catalog.json()
|
325 |
-
except Exception as error:
|
326 |
-
print(error)
|
327 |
-
|
328 |
-
if use_kafka:
|
329 |
-
print("Push picks to kafka...")
|
330 |
-
for pick in picks:
|
331 |
-
producer.send("phasenet_picks", key=pick["id"], value=pick)
|
332 |
-
print("Push waveform to kafka...")
|
333 |
-
for id, timestamp, vec in zip(data.id, data.timestamp, data.vec):
|
334 |
-
producer.send("waveform_phasenet", key=id, value={"timestamp": timestamp, "vec": vec, "dt": data.dt})
|
335 |
-
|
336 |
-
return return_value
|
337 |
-
|
338 |
-
|
339 |
@app.get("/healthz")
|
340 |
def healthz():
|
341 |
return {"status": "ok"}
|
342 |
|
|
|
343 |
@app.get("/")
|
344 |
-
def
|
345 |
-
return {"Hello": "PhaseNet!"}
|
|
|
1 |
import os
|
2 |
+
from collections import defaultdict
|
3 |
from datetime import datetime, timedelta
|
4 |
+
from typing import Any, AnyStr, Dict, List, NamedTuple, Optional, Union
|
|
|
5 |
|
6 |
import numpy as np
|
|
|
7 |
import tensorflow as tf
|
8 |
from fastapi import FastAPI, WebSocket
|
9 |
+
from postprocess import extract_picks
|
10 |
from pydantic import BaseModel
|
11 |
from scipy.interpolate import interp1d
|
12 |
|
13 |
+
from model import UNet
|
14 |
+
|
15 |
+
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
|
16 |
|
17 |
tf.compat.v1.disable_eager_execution()
|
18 |
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
|
|
|
19 |
JSONObject = Dict[AnyStr, Any]
|
20 |
JSONArray = List[Any]
|
21 |
JSONStructure = Union[JSONArray, JSONObject]
|
|
|
37 |
print(f"restoring model {latest_check_point}")
|
38 |
saver.restore(sess, latest_check_point)
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
def normalize_batch(data, window=3000):
|
42 |
"""
|
|
|
171 |
|
172 |
|
173 |
class Data(BaseModel):
|
174 |
+
id: List[List[str]]
|
|
|
|
|
|
|
175 |
timestamp: List[Union[str, float, datetime]]
|
176 |
vec: Union[List[List[List[float]]], List[List[float]]]
|
177 |
|
|
|
199 |
return picks
|
200 |
|
201 |
|
202 |
+
@app.post("/predict_prob")
|
203 |
+
def predict(data: Data):
|
204 |
+
picks, preds = get_prediction(data, True)
|
205 |
+
|
206 |
+
return picks, preds.tolist()
|
207 |
+
|
208 |
+
|
209 |
@app.websocket("/ws")
|
210 |
async def websocket_endpoint(websocket: WebSocket):
|
211 |
await websocket.accept()
|
|
|
218 |
print("PhaseNet Updating...")
|
219 |
|
220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
@app.get("/healthz")
|
222 |
def healthz():
|
223 |
return {"status": "ok"}
|
224 |
|
225 |
+
|
226 |
@app.get("/")
|
227 |
+
def greet_json():
|
228 |
+
return {"Hello": "PhaseNet!"}
|