import gradio as gr import pandas as pd import numpy as np import plotly.graph_objects as go import os, random, math # -------------------------------------------------- # Paths # -------------------------------------------------- PATH_FINAL = "final_combined_full_table.csv" PATH_XTEST = "X_test_target.csv" PATH_OUTPUT = "output.csv" GLOBE_R = 6371 # Earth radius # -------------------------------------------------- # Utility: seeded random vector # -------------------------------------------------- def seeded_vec(seed): r = random.Random(seed) phi = r.random() * 2 * math.pi cos_t = 2 * r.random() - 1 sin_t = math.sqrt(1 - cos_t * cos_t) return np.array([sin_t * math.cos(phi), sin_t * math.sin(phi), cos_t]) # -------------------------------------------------- # Load data # -------------------------------------------------- df_final = pd.read_csv(PATH_FINAL) df_xtest = pd.read_csv(PATH_XTEST) df_output = pd.read_csv(PATH_OUTPUT) # -------------------------------------------------- # Synthesize positions if missing # -------------------------------------------------- if not {"relative_position_r", "relative_position_t", "relative_position_n"}.issubset(df_final.columns): mags = df_final["rel_pos_mag"].fillna(1).values xs, ys, zs = [], [], [] for cid, mag in zip(df_final["conjunction_id"], mags): v = seeded_vec(int(cid)) v *= float(mag) xs.append(v[0]) ys.append(v[1]) zs.append(v[2]) df_final["relative_position_r"] = xs df_final["relative_position_t"] = ys df_final["relative_position_n"] = zs # -------------------------------------------------- # Color mapping # -------------------------------------------------- def alert_color(level): L = str(level).upper() if "HIGH" in L: return "#ff1744" if "MEDIUM" in L: return "#ff9100" if "LOW" in L: return "#00e676" return "#9e9e9e" df_final["_color"] = df_final["dl_score_level"].apply(alert_color) # -------------------------------------------------- # 3D Earth # -------------------------------------------------- def make_earth(): u = np.linspace(0, 2 * np.pi, 72) v = np.linspace(0, np.pi, 36) u, v = np.meshgrid(u, v) x = GLOBE_R * np.cos(u) * np.sin(v) y = GLOBE_R * np.sin(u) * np.sin(v) z = GLOBE_R * np.cos(v) return go.Surface( x=x, y=y, z=z, showscale=False, opacity=0.90, colorscale=[[0, "black"], [1, "#1e3a8a"]], ) # -------------------------------------------------- # Build 3D Visualization # -------------------------------------------------- def build_orbit_plot(orbit, frame, highlight): sub = df_final.copy() if orbit != "ALL": sub = sub[sub["orbit_regime"] == orbit] sub = sub[sub["conjunction_id"] % 200 == frame] SCALE = 4.5 fig = go.Figure() fig.add_trace(make_earth()) xs = GLOBE_R + sub["relative_position_r"].astype(float) * SCALE ys = GLOBE_R + sub["relative_position_t"].astype(float) * SCALE zs = GLOBE_R + sub["relative_position_n"].astype(float) * SCALE fig.add_trace( go.Scatter3d( x=xs, y=ys, z=zs, mode="markers", marker=dict(size=3, color=sub["_color"], opacity=0.95), text=sub["conjunction_id"].astype(str), hoverinfo="text", name="Conjunction Events", ) ) if highlight: try: cid = int(highlight) t = df_final[df_final["conjunction_id"] == cid] if not t.empty: xs2 = GLOBE_R + t["relative_position_r"].astype(float) * SCALE ys2 = GLOBE_R + t["relative_position_t"].astype(float) * SCALE zs2 = GLOBE_R + t["relative_position_n"].astype(float) * SCALE fig.add_trace( go.Scatter3d( x=xs2, y=ys2, z=zs2, mode="lines+markers", line=dict(width=6, color="yellow"), marker=dict(size=6, color="yellow"), name=f"Track {cid}", ) ) except: pass fig.update_layout( scene=dict( xaxis=dict(visible=False), yaxis=dict(visible=False), zaxis=dict(visible=False), ), template="plotly_dark", height=650, margin=dict(l=0, r=0, t=40, b=0), ) return fig # -------------------------------------------------- # Top alerts table # -------------------------------------------------- def top_alerts(n): cols = [ "conjunction_id", "orbit_regime", "dl_score_fixed", "dl_score_level", "ppo_action_name", "final_mode_fixed", ] if n <= 0: return pd.DataFrame() return df_final.sort_values("dl_score_fixed", ascending=False)[cols].head(n) # -------------------------------------------------- # Inspector # -------------------------------------------------- def inspect_event(cid): try: cid = int(cid) except: return pd.DataFrame(), "Invalid ID" row = df_final[df_final["conjunction_id"] == cid] if row.empty: return pd.DataFrame(), "Not Found" r = row.iloc[0] txt = f""" Orbit Regime: {r.get('orbit_regime')} Miss Distance: {r.get('miss_distance')} DL Score: {r.get('dl_score_fixed')} ({r.get('dl_score_level')}) PPO Action: {r.get('ppo_action_name')} Final Mode: {r.get('final_mode_fixed')} """ return row, txt # -------------------------------------------------- # Custom Dark Mode CSS # -------------------------------------------------- dark_css = """ body { background-color: #111 !important; color: white !important; } .gradio-container { background-color: #111 !important; } label, input, textarea { color: white !important; } """ # -------------------------------------------------- # UI # -------------------------------------------------- orbit_list = ["ALL"] + sorted(df_final["orbit_regime"].dropna().unique().tolist()) with gr.Blocks(title="Space Collision Dashboard") as demo: gr.HTML(f"") gr.Markdown( "