zhuwq0 commited on
Commit
1f0ad3c
·
1 Parent(s): 17f2f92

update app.py

Browse files
Files changed (2) hide show
  1. app.py +127 -134
  2. example_fastapi.ipynb +0 -0
app.py CHANGED
@@ -5,165 +5,158 @@ from typing import Dict, List, Union
5
  import numpy as np
6
  import pandas as pd
7
  from fastapi import FastAPI
8
- from gamma.utils import association
9
  from pydantic import BaseModel
10
  from pyproj import Proj
11
 
12
- app = FastAPI()
13
 
14
- PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
15
- # STATION_CSV = os.path.join(PROJECT_ROOT, "tests/stations_hawaii.csv")
16
- # STATION_CSV = os.path.join(PROJECT_ROOT, "tests/stations.csv") ## ridgecrest
17
-
18
-
19
- def default_config(config):
20
- if "degree2km" not in config:
21
- config["degree2km"] = 111.195
22
- if "use_amplitude" not in config:
23
- config["use_amplitude"] = True
24
- if "use_dbscan" not in config:
25
- config["use_dbscan"] = True
26
- if "dbscan_eps" not in config:
27
- config["dbscan_eps"] = 30.0
28
- if "dbscan_min_samples" not in config:
29
- config["dbscan_min_samples"] = 3
30
- if "method" not in config:
31
- config["method"] = "BGMM"
32
- if "oversample_factor" not in config:
33
- config["oversample_factor"] = 5
34
- if "min_picks_per_eq" not in config:
35
- config["min_picks_per_eq"] = 10
36
- if "max_sigma11" not in config:
37
- config["max_sigma11"] = 2.0
38
- if "max_sigma22" not in config:
39
- config["max_sigma22"] = 1.0
40
- if "max_sigma12" not in config:
41
- config["max_sigma12"] = 1.0
42
- if "dims" not in config:
43
- config["dims"] = ["x(km)", "y(km)", "z(km)"]
44
- return config
45
 
46
 
47
- ## set config
48
- config = {"xlim_degree": [-156.32, -154.32], "ylim_degree": [18.39, 20.39], "z(km)": [0, 41]} ## hawaii
49
- # config = {'xlim_degree': [-118.004, -117.004], 'ylim_degree': [35.205, 36.205], "z(km)": [0, 41]} ## ridgecrest
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- config = default_config(config)
52
- config["center"] = [np.mean(config["xlim_degree"]), np.mean(config["ylim_degree"])]
53
- config["x(km)"] = (np.array(config["xlim_degree"]) - config["center"][0]) * config["degree2km"]
54
- config["y(km)"] = (np.array(config["ylim_degree"]) - config["center"][1]) * config["degree2km"]
55
- config["bfgs_bounds"] = [list(config[x]) for x in config["dims"]] + [[None, None]]
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
- for k, v in config.items():
58
- print(f"{k}: {v}")
 
 
 
 
 
 
 
 
59
 
60
- # ## read stations
61
- # stations = pd.read_csv(STATION_CSV, delimiter="\t")
62
- # stations = stations.rename(columns={"station": "id"})
63
- # stations["x(km)"] = stations["longitude"].apply(lambda x: (x - config["center"][0]) * config["degree2km"])
64
- # stations["y(km)"] = stations["latitude"].apply(lambda x: (x - config["center"][1]) * config["degree2km"])
65
- # stations["z(km)"] = stations["elevation(m)"].apply(lambda x: -x / 1e3)
 
 
 
 
 
 
 
 
 
66
 
67
- # print(stations)
68
 
 
69
 
70
- class Data(BaseModel):
71
- picks: List[Dict[str, Union[float, str]]]
72
- stations: List[Dict[str, Union[float, str]]]
73
- config: Dict[str, Union[List[float], List[int], List[str], float, int, str]]
74
 
 
75
 
76
- class Pick(BaseModel):
77
- picks: List[Dict[str, Union[float, str]]]
78
 
 
79
 
80
- def run_gamma(picks, config, stations):
 
81
 
82
- proj = Proj(f"+proj=sterea +lon_0={config['center'][0]} +lat_0={config['center'][1]} +units=km")
83
 
 
 
 
 
 
 
 
 
 
84
  stations[["x(km)", "y(km)"]] = stations.apply(
85
  lambda x: pd.Series(proj(longitude=x.longitude, latitude=x.latitude)), axis=1
86
  )
87
- stations["z(km)"] = stations["elevation(m)"].apply(lambda x: -x / 1e3)
88
-
89
- print(f"{len(picks)} picks, {len(stations)} stations")
90
- catalogs, assignments = association(picks, stations, config, 0, config["method"])
91
 
92
- catalogs = pd.DataFrame(
93
- catalogs,
94
- columns=["time"]
95
- + config["dims"]
96
- + ["magnitude", "sigma_time", "sigma_amp", "cov_time_amp", "event_index", "gamma_score"],
97
- )
98
- if len(catalogs) == 0:
99
- print("No events associated")
100
- return pd.DataFrame(), pd.DataFrame()
101
 
102
- catalogs[["longitude", "latitude"]] = catalogs.apply(
 
 
103
  lambda x: pd.Series(proj(longitude=x["x(km)"], latitude=x["y(km)"], inverse=True)), axis=1
104
  )
105
- catalogs["depth(m)"] = catalogs["z(km)"].apply(lambda x: x * 1e3)
 
 
 
 
 
 
 
 
 
 
106
 
107
  assignments = pd.DataFrame(assignments, columns=["pick_index", "event_index", "gamma_score"])
108
- picks_gamma = picks.join(assignments.set_index("pick_index")).fillna(-1).astype({"event_index": int})
109
-
110
- return catalogs, picks_gamma
111
-
112
-
113
- # @app.post("/predict_stream")
114
- # def predict(data: Pick):
115
-
116
- # picks = pd.DataFrame(data.picks)
117
- # if len(picks) == 0:
118
- # return {"catalog": [], "picks": []}
119
-
120
- # catalogs, picks_gamma = run_gamma(data, config, stations)
121
-
122
- # return {"catalog": catalogs.to_dict(orient="records"), "picks": picks_gamma.to_dict(orient="records")}
123
-
124
-
125
- @app.post("/predict")
126
- def predict(data: Data):
127
-
128
- picks = pd.DataFrame(data.picks)
129
- if len(picks) == 0:
130
- return {"catalog": [], "picks": []}
131
-
132
- stations = pd.DataFrame(data.stations)
133
- if len(stations) == 0:
134
- return {"catalog": [], "picks": []}
135
-
136
- assert "latitude" in stations
137
- assert "longitude" in stations
138
- assert "elevation(m)" in stations
139
-
140
- config = data.config
141
- config = default_config(config)
142
-
143
- if "xlim_degree" not in config:
144
- config["xlim_degree"] = (stations["longitude"].min(), stations["longitude"].max())
145
- if "ylim_degree" not in config:
146
- config["ylim_degree"] = (stations["latitude"].min(), stations["latitude"].max())
147
- if "center" not in config:
148
- config["center"] = [np.mean(config["xlim_degree"]), np.mean(config["ylim_degree"])]
149
- if "x(km)" not in config:
150
- config["x(km)"] = (
151
- (np.array(config["xlim_degree"]) - config["center"][0])
152
- * config["degree2km"]
153
- * np.cos(np.deg2rad(config["center"][1]))
154
- )
155
- if "y(km)" not in config:
156
- config["y(km)"] = (np.array(config["ylim_degree"]) - config["center"][1]) * config["degree2km"]
157
- if "z(km)" not in config:
158
- config["z(km)"] = (0, 41)
159
- if "bfgs_bounds" not in config:
160
- config["bfgs_bounds"] = [list(config[x]) for x in config["dims"]] + [[None, None]]
161
-
162
- catalogs, picks_gamma = run_gamma(picks, config, stations)
163
-
164
- return {"catalog": catalogs.to_dict(orient="records"), "picks": picks_gamma.to_dict(orient="records")}
165
-
166
 
167
- @app.get("/healthz")
168
- def healthz():
169
- return {"status": "ok"}
 
5
  import numpy as np
6
  import pandas as pd
7
  from fastapi import FastAPI
8
+ from kafka import KafkaProducer
9
  from pydantic import BaseModel
10
  from pyproj import Proj
11
 
12
+ from gamma.utils import association
13
 
14
+ app = FastAPI()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
 
17
+ @app.get("/")
18
+ def greet_json():
19
+ return {"message": "Hello, World!"}
20
+
21
+
22
+ @app.post("/predict/")
23
+ def predict(picks: dict, stations: dict, config: dict):
24
+ picks = picks["data"]
25
+ stations = stations["data"]
26
+ picks = pd.DataFrame(picks)
27
+ picks["phase_time"] = pd.to_datetime(picks["phase_time"])
28
+ stations = pd.DataFrame(stations)
29
+ print(stations)
30
+ events_, picks_ = run_gamma(picks, stations, config)
31
+ picks_ = picks_.to_dict(orient="records")
32
+ events_ = events_.to_dict(orient="records")
33
+
34
+ return {"picks": picks_, "events": events_}
35
+
36
+
37
+ def set_config(region="ridgecrest"):
38
+
39
+ config = {
40
+ "min_picks": 8,
41
+ "min_picks_ratio": 0.2,
42
+ "max_residual_time": 1.0,
43
+ "max_residual_amplitude": 1.0,
44
+ "min_score": 0.6,
45
+ "min_s_picks": 2,
46
+ "min_p_picks": 2,
47
+ "use_amplitude": False,
48
+ }
49
+
50
+ # ## Domain
51
+ if region.lower() == "ridgecrest":
52
+ config.update(
53
+ {
54
+ "region": "ridgecrest",
55
+ "minlongitude": -118.004,
56
+ "maxlongitude": -117.004,
57
+ "minlatitude": 35.205,
58
+ "maxlatitude": 36.205,
59
+ "mindepth_km": 0.0,
60
+ "maxdepth_km": 30.0,
61
+ }
62
+ )
63
 
64
+ lon0 = (config["minlongitude"] + config["maxlongitude"]) / 2
65
+ lat0 = (config["minlatitude"] + config["maxlatitude"]) / 2
66
+ proj = Proj(f"+proj=sterea +lon_0={lon0} +lat_0={lat0} +units=km")
67
+ xmin, ymin = proj(config["minlongitude"], config["minlatitude"])
68
+ xmax, ymax = proj(config["maxlongitude"], config["maxlatitude"])
69
+ zmin, zmax = config["mindepth_km"], config["maxdepth_km"]
70
+ xlim_km = (xmin, xmax)
71
+ ylim_km = (ymin, ymax)
72
+ zlim_km = (zmin, zmax)
73
+
74
+ config.update(
75
+ {
76
+ "xlim_km": xlim_km,
77
+ "ylim_km": ylim_km,
78
+ "zlim_km": zlim_km,
79
+ "proj": proj,
80
+ }
81
+ )
82
 
83
+ config.update(
84
+ {
85
+ "min_picks_per_eq": 5,
86
+ "min_p_picks_per_eq": 0,
87
+ "min_s_picks_per_eq": 0,
88
+ "max_sigma11": 3.0,
89
+ "max_sigma22": 1.0,
90
+ "max_sigma12": 1.0,
91
+ }
92
+ )
93
 
94
+ config["use_dbscan"] = False
95
+ config["use_amplitude"] = True
96
+ config["oversample_factor"] = 8.0
97
+ config["dims"] = ["x(km)", "y(km)", "z(km)"]
98
+ config["method"] = "BGMM"
99
+ config["ncpu"] = 1
100
+ vel = {"p": 6.0, "s": 6.0 / 1.75}
101
+ config["vel"] = vel
102
+
103
+ config["bfgs_bounds"] = (
104
+ (xlim_km[0] - 1, xlim_km[1] + 1), # x
105
+ (ylim_km[0] - 1, ylim_km[1] + 1), # y
106
+ (0, zlim_km[1] + 1), # z
107
+ (None, None), # t
108
+ )
109
 
110
+ config["event_index"] = 0
111
 
112
+ return config
113
 
 
 
 
 
114
 
115
+ config = set_config()
116
 
 
 
117
 
118
+ def run_gamma(picks, stations, config_):
119
 
120
+ # %%
121
+ config.update(config_)
122
 
123
+ proj = config["proj"]
124
 
125
+ picks = picks.rename(
126
+ columns={
127
+ "station_id": "id",
128
+ "phase_time": "timestamp",
129
+ "phase_type": "type",
130
+ "phase_score": "prob",
131
+ "phase_amplitude": "amp",
132
+ }
133
+ )
134
  stations[["x(km)", "y(km)"]] = stations.apply(
135
  lambda x: pd.Series(proj(longitude=x.longitude, latitude=x.latitude)), axis=1
136
  )
137
+ stations["z(km)"] = stations["elevation_m"].apply(lambda x: -x / 1e3)
138
+ stations = stations.rename(columns={"station_id": "id"})
 
 
139
 
140
+ events, assignments = association(picks, stations, config, 0, config["method"])
 
 
 
 
 
 
 
 
141
 
142
+ print(events)
143
+ events = pd.DataFrame(events)
144
+ events[["longitude", "latitude"]] = events.apply(
145
  lambda x: pd.Series(proj(longitude=x["x(km)"], latitude=x["y(km)"], inverse=True)), axis=1
146
  )
147
+ events["depth_km"] = events["z(km)"]
148
+ events.drop(columns=["x(km)", "y(km)", "z(km)"], inplace=True, errors="ignore")
149
+ picks = picks.rename(
150
+ columns={
151
+ "id": "station_id",
152
+ "timestamp": "phase_time",
153
+ "type": "phase_type",
154
+ "prob": "phase_score",
155
+ "amp": "phase_amplitude",
156
+ }
157
+ )
158
 
159
  assignments = pd.DataFrame(assignments, columns=["pick_index", "event_index", "gamma_score"])
160
+ picks = picks.join(assignments.set_index("pick_index")).fillna(-1).astype({"event_index": int})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
+ return events, picks
 
 
example_fastapi.ipynb ADDED
The diff for this file is too large to render. See raw diff