Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -125,6 +125,30 @@ def predict_flash_flood(rainfall, slope, drainage, saturation, convergence, use_
|
|
| 125 |
else:
|
| 126 |
return f"🛡️ Flash Flood Unlikely ({adjusted:.2f})"
|
| 127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
|
| 129 |
def generate_plot(axis, use_trustnet):
|
| 130 |
sweep_values = np.linspace({
|
|
@@ -302,6 +326,51 @@ def generate_flash_plot(axis, use_trust):
|
|
| 302 |
ax.grid(True)
|
| 303 |
return fig
|
| 304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
with gr.Blocks(theme=gr.themes.Default(), css=".tab-nav-button { font-size: 1.1rem !important; padding: 0.8em; } ") as demo:
|
| 306 |
gr.Markdown("# ClimateNet - A family of tabular classification models to predict natural disasters")
|
| 307 |
|
|
@@ -550,6 +619,72 @@ with gr.Blocks(theme=gr.themes.Default(), css=".tab-nav-button { font-size: 1.1r
|
|
| 550 |
outputs=[flash_output, flash_plot]
|
| 551 |
)
|
| 552 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
app = FastAPI()
|
| 554 |
|
| 555 |
app.add_middleware(
|
|
|
|
| 125 |
else:
|
| 126 |
return f"🛡️ Flash Flood Unlikely ({adjusted:.2f})"
|
| 127 |
|
| 128 |
+
def predict_quake(dotM0, sdr, coulomb, afd, fsr, use_trust):
|
| 129 |
+
dotM0 = dotM0 * 1e16
|
| 130 |
+
|
| 131 |
+
input_data = {
|
| 132 |
+
"seismic_moment_rate": dotM0,
|
| 133 |
+
"surface_displacement_rate": sdr,
|
| 134 |
+
"coulomb_stress_change": coulomb,
|
| 135 |
+
"average_focal_depth": afd,
|
| 136 |
+
"fault_slip_rate": fsr
|
| 137 |
+
}
|
| 138 |
+
input_df = pd.DataFrame([input_data])
|
| 139 |
+
base_pred = QuakeNet.predict(input_df)[0][0]
|
| 140 |
+
if use_trust:
|
| 141 |
+
trust_score = QuakeTrustNet.predict(QuakeTrustScaler.transform(input_df))[0][0]
|
| 142 |
+
adjusted = np.clip(base_pred * trust_score, 0, 1)
|
| 143 |
+
else:
|
| 144 |
+
adjusted = base_pred
|
| 145 |
+
|
| 146 |
+
if adjusted > 0.55:
|
| 147 |
+
return f"🌎 EARTHQUAKE LIKELY ({adjusted:.2f})"
|
| 148 |
+
elif 0.40 < adjusted <= 0.55:
|
| 149 |
+
return f"⚠️ Earthquake Possible ({adjusted:.2f})"
|
| 150 |
+
else:
|
| 151 |
+
return f"🛡️ Earthquake Unlikely ({adjusted:.2f})"
|
| 152 |
|
| 153 |
def generate_plot(axis, use_trustnet):
|
| 154 |
sweep_values = np.linspace({
|
|
|
|
| 326 |
ax.grid(True)
|
| 327 |
return fig
|
| 328 |
|
| 329 |
+
def generate_quake_plot(axis, use_trustnet):
|
| 330 |
+
|
| 331 |
+
axis_ranges = {
|
| 332 |
+
"seismic_moment_rate": (5e14, 2.5e16),
|
| 333 |
+
"surface_displacement_rate": (0, 100),
|
| 334 |
+
"coulomb_stress_change": (0, 700),
|
| 335 |
+
"average_focal_depth": (0, 60),
|
| 336 |
+
"fault_slip_rate": (0, 20)
|
| 337 |
+
}
|
| 338 |
+
sweep_values = np.linspace(*axis_ranges[axis], 100)
|
| 339 |
+
|
| 340 |
+
# Baseline input for all other features
|
| 341 |
+
base_input = {
|
| 342 |
+
"seismic_moment_rate": 1.5e16,
|
| 343 |
+
"surface_displacement_rate": 35,
|
| 344 |
+
"coulomb_stress_change": 300,
|
| 345 |
+
"average_focal_depth": 18,
|
| 346 |
+
"fault_slip_rate": 7.0
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
# Create sweep dataframe
|
| 350 |
+
sweep_df = pd.DataFrame([{**base_input, axis: val} for val in sweep_values])
|
| 351 |
+
raw_preds = QuakeNet.predict(sweep_df).flatten()
|
| 352 |
+
|
| 353 |
+
if use_trustnet:
|
| 354 |
+
scaled_df = QuakeTrustScaler.transform(sweep_df)
|
| 355 |
+
trust_scores = QuakeTrustNet.predict(scaled_df).flatten()
|
| 356 |
+
modulated = np.clip(raw_preds * trust_scores, 0, 1)
|
| 357 |
+
else:
|
| 358 |
+
modulated = raw_preds
|
| 359 |
+
|
| 360 |
+
# Plot
|
| 361 |
+
fig, ax = plt.subplots()
|
| 362 |
+
ax.plot(sweep_values, raw_preds, "--", color="gray", label="QuakeNet")
|
| 363 |
+
if use_trustnet:
|
| 364 |
+
ax.plot(sweep_values, modulated, color="darkred", label="With QuakeTrustNet")
|
| 365 |
+
ax.set_xlabel(axis.replace("_", " ").title())
|
| 366 |
+
ax.set_ylabel("Quake Probability")
|
| 367 |
+
ax.set_title(f"Earthquake Likelihood vs. {axis.replace('_', ' ').title()}")
|
| 368 |
+
ax.legend()
|
| 369 |
+
ax.grid(True)
|
| 370 |
+
|
| 371 |
+
return fig
|
| 372 |
+
|
| 373 |
+
|
| 374 |
with gr.Blocks(theme=gr.themes.Default(), css=".tab-nav-button { font-size: 1.1rem !important; padding: 0.8em; } ") as demo:
|
| 375 |
gr.Markdown("# ClimateNet - A family of tabular classification models to predict natural disasters")
|
| 376 |
|
|
|
|
| 619 |
outputs=[flash_output, flash_plot]
|
| 620 |
)
|
| 621 |
|
| 622 |
+
with gr.Tab("🌎 Earthquakes"):
|
| 623 |
+
with gr.Row():
|
| 624 |
+
with gr.Column():
|
| 625 |
+
with gr.Row():
|
| 626 |
+
moment_input = gr.Slider(
|
| 627 |
+
minimum=0.5, maximum=25.0, value=15.0,
|
| 628 |
+
label="Seismic Moment Rate (×10¹⁶ Nm/s)"
|
| 629 |
+
)
|
| 630 |
+
gr.Dropdown(["Nm/s"], value="Nm/s", label="", scale=0.2)
|
| 631 |
+
|
| 632 |
+
with gr.Row():
|
| 633 |
+
displacement_input = gr.Slider(0, 100, value=35, label="Surface Displacement Rate (mm/yr)")
|
| 634 |
+
gr.Dropdown(["mm/yr"], value="mm/yr", label="", scale=0.2)
|
| 635 |
+
|
| 636 |
+
with gr.Row():
|
| 637 |
+
stress_input = gr.Slider(0, 700, value=300, label="Coulomb Stress Change (Pa)")
|
| 638 |
+
gr.Dropdown(["Pa"], value="Pa", label="", scale=0.2)
|
| 639 |
+
|
| 640 |
+
with gr.Row():
|
| 641 |
+
depth_input = gr.Slider(0, 60, value=18, label="Average Focal Depth (km)")
|
| 642 |
+
gr.Dropdown(["km"], value="km", label="", scale=0.2)
|
| 643 |
+
|
| 644 |
+
with gr.Row():
|
| 645 |
+
slip_input = gr.Slider(0, 20, value=7.0, label="Fault Slip Rate (mm/yr)")
|
| 646 |
+
gr.Dropdown(["mm/yr"], value="mm/yr", label="", scale=0.2)
|
| 647 |
+
|
| 648 |
+
use_trust_quake = gr.Checkbox(label="Use QuakeTrustNet", value=True)
|
| 649 |
+
|
| 650 |
+
quake_sweep_axis = gr.Radio(
|
| 651 |
+
["seismic_moment_rate", "surface_displacement_rate",
|
| 652 |
+
"coulomb_stress_change", "average_focal_depth", "fault_slip_rate"],
|
| 653 |
+
label="Sweep Axis", value="seismic_moment_rate"
|
| 654 |
+
)
|
| 655 |
+
|
| 656 |
+
quake_predict_btn = gr.Button("Predict")
|
| 657 |
+
|
| 658 |
+
with gr.Column():
|
| 659 |
+
with gr.Accordion("ℹ️ Feature Definitions", open=False):
|
| 660 |
+
gr.Markdown("""
|
| 661 |
+
**Seismic Moment Rate (Nm/s):** Total energy release rate from seismic events.
|
| 662 |
+
|
| 663 |
+
**Surface Displacement Rate (mm/yr):** Horizontal/vertical ground motion observed via GPS/InSAR.
|
| 664 |
+
|
| 665 |
+
**Coulomb Stress Change (Pa):** Fault stress changes post-seismic activity.
|
| 666 |
+
|
| 667 |
+
**Average Focal Depth (km):** Typical depth of earthquakes in the region.
|
| 668 |
+
|
| 669 |
+
**Fault Slip Rate (mm/yr):** Long-term fault motion due to tectonic loading.
|
| 670 |
+
""")
|
| 671 |
+
|
| 672 |
+
quake_output = gr.Textbox(label="Earthquake Risk Verdict")
|
| 673 |
+
quake_plot = gr.Plot(label="Trust Modulation Plot")
|
| 674 |
+
|
| 675 |
+
quake_predict_btn.click(
|
| 676 |
+
fn=lambda m, d, s, dp, sl, trust, axis: (
|
| 677 |
+
predict_quake(m, d, s, dp, sl, trust),
|
| 678 |
+
generate_quake_plot(axis, trust)
|
| 679 |
+
),
|
| 680 |
+
inputs=[
|
| 681 |
+
moment_input, displacement_input,
|
| 682 |
+
stress_input, depth_input, slip_input,
|
| 683 |
+
use_trust_quake, quake_sweep_axis
|
| 684 |
+
],
|
| 685 |
+
outputs=[quake_output, quake_plot]
|
| 686 |
+
)
|
| 687 |
+
|
| 688 |
app = FastAPI()
|
| 689 |
|
| 690 |
app.add_middleware(
|