| import streamlit as st
|
| import pandas as pd
|
| import joblib
|
|
|
|
|
| st.set_page_config(
|
| page_title="Thunderstorm Predictor",
|
| page_icon="π¦",
|
| layout="wide"
|
| )
|
|
|
| MODEL_PATH = 'model/Random_Forest_best_model.pkl'
|
|
|
| @st.cache_resource
|
| def load_local_model():
|
| """Caches the model initialization to prevent slow page reloads."""
|
| try:
|
| return joblib.load(MODEL_PATH)
|
| except FileNotFoundError:
|
| st.error(f"β Could not find the model file at `{MODEL_PATH}`. Please check your folder structure.")
|
| return None
|
|
|
| model = load_local_model()
|
|
|
| st.title("π¦ Thunderstorm Prediction App")
|
| st.markdown("Enter atmospheric metrics below to predict the likelihood of real-time Convective Thunderstorm (TH) occurrences.")
|
| st.markdown("---")
|
|
|
|
|
| st.sidebar.header("π‘ Quick-Load Test Profiles")
|
| st.sidebar.write("Click a button below to instantly populate realistic meteorological boundaries into your dashboard:")
|
|
|
| clear_sky_preset = {
|
| "sweat": 91.2, "k": -1.4, "tt": 24.7, "stability": 25.8,
|
| "moisture": 22.8, "convective": 0.0, "temp_press": 5636.0, "profile": 993.98
|
| }
|
|
|
| severe_storm_preset = {
|
| "sweat": 420.0, "k": 38.0, "tt": 56.0, "stability": -10.0,
|
| "moisture": 55.0, "convective": 2500.0, "temp_press": 5700.0, "profile": 900.00
|
| }
|
|
|
|
|
| if "form_data" not in st.session_state:
|
| st.session_state.form_data = clear_sky_preset
|
|
|
| if st.sidebar.button("βοΈ Populate Clear Skies Profile"):
|
| st.session_state.form_data = clear_sky_preset
|
|
|
| if st.sidebar.button("π¨ Populate Severe Thunderstorm Profile"):
|
| st.session_state.form_data = severe_storm_preset
|
|
|
|
|
|
|
| st.subheader("π Ambient Atmospheric Parameters")
|
| col1, col2 = st.columns(2)
|
|
|
| with col1:
|
| st.markdown("### π‘οΈ Thermal & Stability Indices")
|
| SWEAT_index = st.number_input("SWEAT Index", value=st.session_state.form_data["sweat"], help="Severe Weather Threat Index baseline.")
|
| K_index = st.number_input("K Index", value=st.session_state.form_data["k"], help="Vertical temperature lapse tracking point.")
|
| Totals_totals_index = st.number_input("Totals Totals Index", value=st.session_state.form_data["tt"], help="Static stability framework element.")
|
| Environmental_Stability = st.number_input("Environmental Stability", value=st.session_state.form_data["stability"], help="Calculated using Showalter + Lifted. Highly negative values imply extreme updraft potential.")
|
|
|
| with col2:
|
| st.markdown("### π§ Moisture & Geometric Profiles")
|
| Moisture_Indices = st.number_input("Moisture Indices", value=st.session_state.form_data["moisture"], help="Precipitable water depth saturation calculation.")
|
| Convective_Potential = st.number_input("Convective Potential", value=st.session_state.form_data["convective"], help="Calculated using CAPE + CINE energy thresholds.")
|
| Temperature_Pressure = st.number_input("Temperature Pressure", value=st.session_state.form_data["temp_press"], help="1000-500 hPa Thickness index framework metric.")
|
| Moisture_Temperature_Profiles = st.number_input("Moisture Temperature Profiles", value=st.session_state.form_data["profile"], help="Pressure at Lifted Condensation Level (PLCL).")
|
|
|
| st.markdown("---")
|
|
|
|
|
|
|
| if st.button("π Run Convective Thunderstorm Prediction", use_container_width=True):
|
| if model is not None:
|
|
|
| input_df = pd.DataFrame([{
|
| "SWEAT index": SWEAT_index,
|
| "K index": K_index,
|
| "Totals totals index": Totals_totals_index,
|
| "Environmental_Stability": Environmental_Stability,
|
| "Moisture_Indices": Moisture_Indices,
|
| "Convective_Potential": Convective_Potential,
|
| "Temperature_Pressure": Temperature_Pressure,
|
| "Moisture_Temperature_Profiles": Moisture_Temperature_Profiles
|
| }])
|
|
|
| try:
|
| prediction = int(model.predict(input_df)[0])
|
| probability = float(model.predict_proba(input_df)[0][1])
|
|
|
| st.subheader("π― Model Execution Analysis")
|
| out_col1, out_col2 = st.columns(2)
|
|
|
| with out_col1:
|
| if prediction == 1:
|
| st.error("π¨ THUNDERSTORM DETECTED / CONVECTIVE CONDITIONS MET")
|
| else:
|
| st.success("βοΈ CLEAR WEATHER / NO CONVECTIVE THREAT")
|
|
|
| st.metric(label="Target Class Output (TH)", value=f"Class {prediction}")
|
|
|
| with out_col2:
|
| st.write(f"**Convective Saturation Confidence:** {probability * 100:.2f}%")
|
| st.progress(probability)
|
| st.caption("Probability threshold marker: Classification triggers class 1 above 50.00%.")
|
|
|
| except Exception as e:
|
| st.error("β οΈ Model Matrix Dimensions Do Not Match.")
|
| st.markdown(f"Your model failed execution because it expects a different number of columns. "
|
| f"**Underlying System Exception:** `{str(e)}`")
|
|
|