Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
# ==============================================================================
|
| 2 |
# SYSTEM: SADIM AI RADAR 77M - ADVANCED TACTICAL EXPERT INTERFACE
|
| 3 |
-
# VERSION: 4.
|
| 4 |
# ==============================================================================
|
| 5 |
|
| 6 |
import streamlit as st
|
|
@@ -25,7 +25,7 @@ st.set_page_config(
|
|
| 25 |
)
|
| 26 |
|
| 27 |
# ------------------------------------------------------------------------------
|
| 28 |
-
# 2. ADVANCED CSS STYLING (
|
| 29 |
# ------------------------------------------------------------------------------
|
| 30 |
st.markdown("""
|
| 31 |
<style>
|
|
@@ -42,7 +42,7 @@ st.markdown("""
|
|
| 42 |
/* Hide Native UI */
|
| 43 |
[data-testid="stHeader"], footer { display: none !important; }
|
| 44 |
|
| 45 |
-
/* THE
|
| 46 |
div[data-testid="stHorizontalBlock"] {
|
| 47 |
position: fixed !important;
|
| 48 |
bottom: 30px !important;
|
|
@@ -52,10 +52,9 @@ st.markdown("""
|
|
| 52 |
width: fit-content !important;
|
| 53 |
display: flex !important;
|
| 54 |
flex-direction: row !important;
|
| 55 |
-
gap: 0px !important;
|
| 56 |
align-items: center !important;
|
| 57 |
-
box-shadow:
|
| 58 |
-
border-radius: 20px !important;
|
| 59 |
}
|
| 60 |
|
| 61 |
div[data-testid="column"] {
|
|
@@ -65,51 +64,51 @@ st.markdown("""
|
|
| 65 |
padding: 0 !important;
|
| 66 |
}
|
| 67 |
|
| 68 |
-
/* Input Field */
|
| 69 |
div[data-testid="stTextInput"] {
|
| 70 |
margin-bottom: 0 !important;
|
| 71 |
-
width:
|
| 72 |
}
|
| 73 |
div[data-testid="stTextInput"] > div:first-child { display: none !important; }
|
| 74 |
div[data-testid="stTextInput"] input {
|
| 75 |
-
background-color: #
|
| 76 |
color: #000000 !important;
|
| 77 |
-
border:
|
| 78 |
-
border-right: none !important;
|
| 79 |
font-family: 'Courier New', Courier, monospace !important;
|
| 80 |
font-size: 13px !important;
|
| 81 |
font-weight: bold !important;
|
| 82 |
-
padding: 4px
|
| 83 |
-
border-radius:
|
| 84 |
-
height:
|
| 85 |
outline: none !important;
|
| 86 |
box-shadow: none !important;
|
| 87 |
}
|
| 88 |
|
| 89 |
-
/* Scan Button */
|
| 90 |
div[data-testid="stButton"] {
|
| 91 |
margin-bottom: 0 !important;
|
| 92 |
-
width:
|
| 93 |
}
|
| 94 |
div[data-testid="stButton"] button {
|
| 95 |
-
background-color: #
|
| 96 |
color: #000000 !important;
|
| 97 |
-
border:
|
| 98 |
font-family: 'Arial', sans-serif !important;
|
| 99 |
font-size: 11px !important;
|
| 100 |
font-weight: 900 !important;
|
| 101 |
padding: 0 !important;
|
| 102 |
-
border-radius:
|
| 103 |
text-transform: uppercase !important;
|
| 104 |
-
height:
|
| 105 |
-
line-height:
|
| 106 |
width: 100% !important;
|
| 107 |
-
transition: background-color 0.
|
| 108 |
display: block !important;
|
| 109 |
cursor: crosshair !important;
|
| 110 |
}
|
| 111 |
-
div[data-testid="stButton"] button:hover { background-color: #
|
| 112 |
-
div[data-testid="stButton"] button:active { background-color: #
|
| 113 |
|
| 114 |
/* Aladin Viewport */
|
| 115 |
iframe {
|
|
@@ -218,10 +217,9 @@ def execute_stellar_scan(source_id):
|
|
| 218 |
t_ra = coord_df.iloc[0]['ra']
|
| 219 |
t_dec = coord_df.iloc[0]['dec']
|
| 220 |
|
| 221 |
-
# 4.3. Cone Search (Radius 0.05 degrees)
|
| 222 |
cone_query = f"""
|
| 223 |
-
SELECT source_id, ra, dec, pmra, pmdec, d_pc, abs_m, bp_rp, l, b, x, y, z
|
| 224 |
-
ruwe, parallax_over_error, pmra_error, pmdec_error
|
| 225 |
FROM '{exact_file_path}'
|
| 226 |
WHERE ra BETWEEN {t_ra - 0.05} AND {t_ra + 0.05}
|
| 227 |
AND dec BETWEEN {t_dec - 0.05} AND {t_dec + 0.05}
|
|
@@ -242,11 +240,10 @@ def execute_stellar_scan(source_id):
|
|
| 242 |
return {"error": "TARGET LOST IN CONE SEARCH"}
|
| 243 |
row = target_row.iloc[0]
|
| 244 |
|
| 245 |
-
#
|
| 246 |
-
ruwe_val = row['ruwe'] if pd.notna(row['ruwe']) else 1.0
|
| 247 |
-
plx_err_val = row['parallax_over_error'] if pd.notna(row['parallax_over_error']) else 10.0
|
| 248 |
dist_pc = row['d_pc'] if pd.notna(row['d_pc']) else 1000.0
|
| 249 |
dist_ly = dist_pc * 3.26156
|
|
|
|
| 250 |
pm_total = math.sqrt(row['pmra']**2 + row['pmdec']**2)
|
| 251 |
v_tangential = 4.74 * 1e-3 * pm_total * dist_pc
|
| 252 |
|
|
@@ -285,14 +282,11 @@ def execute_stellar_scan(source_id):
|
|
| 285 |
except Exception:
|
| 286 |
mse_val, kl_val, hybrid_total = 0.0, 0.0, 0.0
|
| 287 |
|
| 288 |
-
# 4.7. The Filter Hierarchy (
|
| 289 |
final_status = "NOMINAL (NORMAL)"
|
| 290 |
final_color = "#888888"
|
| 291 |
|
| 292 |
-
if
|
| 293 |
-
final_status = "DATA ARTIFACT: BAD ASTROMETRY"
|
| 294 |
-
final_color = "#ffaa00" # Orange
|
| 295 |
-
elif v_tangential > 600.0:
|
| 296 |
final_status = "PHYSICAL ANOMALY: HYPERVELOCITY"
|
| 297 |
final_color = "#ff3333" # Red
|
| 298 |
elif is_local_outlier:
|
|
@@ -311,8 +305,7 @@ def execute_stellar_scan(source_id):
|
|
| 311 |
|
| 312 |
result_dict = {
|
| 313 |
'id': source_id, 'ra': row['ra'], 'dec': row['dec'],
|
| 314 |
-
'dist': round(dist_ly, 1), 'vel': round(v_tangential, 2),
|
| 315 |
-
'ruwe': round(ruwe_val, 2),
|
| 316 |
'mse': round(mse_val, 6), 'kl': round(kl_val, 6),
|
| 317 |
'status': final_status, 'color': final_color,
|
| 318 |
'neighbors_js': js_neighbors_array,
|
|
@@ -354,23 +347,23 @@ if st.session_state.session['is_active']:
|
|
| 354 |
state = st.session_state.session
|
| 355 |
if state['has_error']:
|
| 356 |
popup_html_component = f"""
|
| 357 |
-
<div id="pop-win" class="tactical-popup" style="border-color:#ff3333">
|
| 358 |
<div class="pop-header"><span style="color:#ff3333">! ALERT_FAILURE</span><button onclick="document.getElementById('pop-win').style.display='none'" class="pop-close">×</button></div>
|
| 359 |
<div style="color:#ff3333;font-size:11px;text-align:center;padding:10px;font-weight:bold">{state['error_text']}</div>
|
| 360 |
</div>"""
|
| 361 |
elif state['data']:
|
| 362 |
sd = state['data']
|
| 363 |
popup_html_component = f"""
|
| 364 |
-
<div id="pop-win" class="tactical-popup">
|
| 365 |
<div class="pop-header"><span>SADIM 77M // SCAN_REPORT</span><button onclick="document.getElementById('pop-win').style.display='none'" class="pop-close">×</button></div>
|
| 366 |
<div class="pop-section">
|
| 367 |
<div class="pop-row"><span>SOURCE_ID</span><b>{sd['id']}</b></div>
|
| 368 |
<div class="pop-row"><span>DIST_LY</span><b>{sd['dist']}</b></div>
|
|
|
|
| 369 |
<div class="pop-row"><span>VEL_KMS (TAN)</span><b style="color:{'#ff3333' if sd['vel']>600 else '#ffffff'}">{sd['vel']}</b></div>
|
| 370 |
</div>
|
| 371 |
<div class="pop-section">
|
| 372 |
<div class="pop-row"><span>LOCAL NEIGHBORS</span><b>{sd['neighbor_count']} STARS</b></div>
|
| 373 |
-
<div class="pop-row"><span>RUWE (NOISE)</span><b style="color:{'#ffaa00' if sd['ruwe']>1.4 else '#ffffff'}">{sd['ruwe']}</b></div>
|
| 374 |
</div>
|
| 375 |
<div class="pop-section-ai">
|
| 376 |
<div class="pop-row"><span>MSE_DEV</span><b>{sd['mse']}</b></div>
|
|
@@ -396,9 +389,9 @@ radar_logic_html = f"""
|
|
| 396 |
|
| 397 |
.tactical-popup {{
|
| 398 |
position: absolute; top: 25px; right: 25px; z-index: 9999;
|
| 399 |
-
background: rgba(10, 10, 10, 0.
|
| 400 |
-
padding: 15px; font-family: 'Courier New', Courier, monospace; width:
|
| 401 |
-
color: white;
|
| 402 |
}}
|
| 403 |
.pop-header {{
|
| 404 |
display: flex; justify-content: space-between; align-items: center;
|
|
|
|
| 1 |
# ==============================================================================
|
| 2 |
# SYSTEM: SADIM AI RADAR 77M - ADVANCED TACTICAL EXPERT INTERFACE
|
| 3 |
+
# VERSION: 4.2.0 (CLASSIC TERMINAL UI, STABLE CONE SEARCH, PARALLAX)
|
| 4 |
# ==============================================================================
|
| 5 |
|
| 6 |
import streamlit as st
|
|
|
|
| 25 |
)
|
| 26 |
|
| 27 |
# ------------------------------------------------------------------------------
|
| 28 |
+
# 2. ADVANCED CSS STYLING (CLASSIC ACADEMIC TERMINAL UI)
|
| 29 |
# ------------------------------------------------------------------------------
|
| 30 |
st.markdown("""
|
| 31 |
<style>
|
|
|
|
| 42 |
/* Hide Native UI */
|
| 43 |
[data-testid="stHeader"], footer { display: none !important; }
|
| 44 |
|
| 45 |
+
/* THE ACADEMIC SEARCH BAR BLOCK - Sharp Edges, Minimalist */
|
| 46 |
div[data-testid="stHorizontalBlock"] {
|
| 47 |
position: fixed !important;
|
| 48 |
bottom: 30px !important;
|
|
|
|
| 52 |
width: fit-content !important;
|
| 53 |
display: flex !important;
|
| 54 |
flex-direction: row !important;
|
| 55 |
+
gap: 0px !important; /* Zero gap for seamless attachment */
|
| 56 |
align-items: center !important;
|
| 57 |
+
box-shadow: 5px 5px 15px rgba(0,0,0,0.9) !important;
|
|
|
|
| 58 |
}
|
| 59 |
|
| 60 |
div[data-testid="column"] {
|
|
|
|
| 64 |
padding: 0 !important;
|
| 65 |
}
|
| 66 |
|
| 67 |
+
/* Input Field - Classic Rectangle */
|
| 68 |
div[data-testid="stTextInput"] {
|
| 69 |
margin-bottom: 0 !important;
|
| 70 |
+
width: 190px !important;
|
| 71 |
}
|
| 72 |
div[data-testid="stTextInput"] > div:first-child { display: none !important; }
|
| 73 |
div[data-testid="stTextInput"] input {
|
| 74 |
+
background-color: #d8d8d8 !important; /* Classic terminal grey */
|
| 75 |
color: #000000 !important;
|
| 76 |
+
border: 1px solid #555555 !important;
|
| 77 |
+
border-right: none !important; /* Open right edge to fuse with button */
|
| 78 |
font-family: 'Courier New', Courier, monospace !important;
|
| 79 |
font-size: 13px !important;
|
| 80 |
font-weight: bold !important;
|
| 81 |
+
padding: 4px 10px !important;
|
| 82 |
+
border-radius: 0px !important; /* Sharp corners */
|
| 83 |
+
height: 34px !important;
|
| 84 |
outline: none !important;
|
| 85 |
box-shadow: none !important;
|
| 86 |
}
|
| 87 |
|
| 88 |
+
/* Scan Button - Classic Square/Rectangle */
|
| 89 |
div[data-testid="stButton"] {
|
| 90 |
margin-bottom: 0 !important;
|
| 91 |
+
width: 75px !important;
|
| 92 |
}
|
| 93 |
div[data-testid="stButton"] button {
|
| 94 |
+
background-color: #d8d8d8 !important;
|
| 95 |
color: #000000 !important;
|
| 96 |
+
border: 1px solid #555555 !important;
|
| 97 |
font-family: 'Arial', sans-serif !important;
|
| 98 |
font-size: 11px !important;
|
| 99 |
font-weight: 900 !important;
|
| 100 |
padding: 0 !important;
|
| 101 |
+
border-radius: 0px !important; /* Sharp corners */
|
| 102 |
text-transform: uppercase !important;
|
| 103 |
+
height: 34px !important; /* Exact match to input height */
|
| 104 |
+
line-height: 34px !important;
|
| 105 |
width: 100% !important;
|
| 106 |
+
transition: background-color 0.1s;
|
| 107 |
display: block !important;
|
| 108 |
cursor: crosshair !important;
|
| 109 |
}
|
| 110 |
+
div[data-testid="stButton"] button:hover { background-color: #bbbbbb !important; }
|
| 111 |
+
div[data-testid="stButton"] button:active { background-color: #999999 !important; border-color:#000; }
|
| 112 |
|
| 113 |
/* Aladin Viewport */
|
| 114 |
iframe {
|
|
|
|
| 217 |
t_ra = coord_df.iloc[0]['ra']
|
| 218 |
t_dec = coord_df.iloc[0]['dec']
|
| 219 |
|
| 220 |
+
# 4.3. Cone Search (Radius 0.05 degrees)
|
| 221 |
cone_query = f"""
|
| 222 |
+
SELECT source_id, ra, dec, pmra, pmdec, d_pc, abs_m, bp_rp, l, b, x, y, z
|
|
|
|
| 223 |
FROM '{exact_file_path}'
|
| 224 |
WHERE ra BETWEEN {t_ra - 0.05} AND {t_ra + 0.05}
|
| 225 |
AND dec BETWEEN {t_dec - 0.05} AND {t_dec + 0.05}
|
|
|
|
| 240 |
return {"error": "TARGET LOST IN CONE SEARCH"}
|
| 241 |
row = target_row.iloc[0]
|
| 242 |
|
| 243 |
+
# Kinematics & Parallax Math
|
|
|
|
|
|
|
| 244 |
dist_pc = row['d_pc'] if pd.notna(row['d_pc']) else 1000.0
|
| 245 |
dist_ly = dist_pc * 3.26156
|
| 246 |
+
parallax_mas = 1000.0 / dist_pc if dist_pc > 0 else 0.0
|
| 247 |
pm_total = math.sqrt(row['pmra']**2 + row['pmdec']**2)
|
| 248 |
v_tangential = 4.74 * 1e-3 * pm_total * dist_pc
|
| 249 |
|
|
|
|
| 282 |
except Exception:
|
| 283 |
mse_val, kl_val, hybrid_total = 0.0, 0.0, 0.0
|
| 284 |
|
| 285 |
+
# 4.7. The Filter Hierarchy (Physics -> Local -> AI)
|
| 286 |
final_status = "NOMINAL (NORMAL)"
|
| 287 |
final_color = "#888888"
|
| 288 |
|
| 289 |
+
if v_tangential > 600.0:
|
|
|
|
|
|
|
|
|
|
| 290 |
final_status = "PHYSICAL ANOMALY: HYPERVELOCITY"
|
| 291 |
final_color = "#ff3333" # Red
|
| 292 |
elif is_local_outlier:
|
|
|
|
| 305 |
|
| 306 |
result_dict = {
|
| 307 |
'id': source_id, 'ra': row['ra'], 'dec': row['dec'],
|
| 308 |
+
'dist': round(dist_ly, 1), 'plx': round(parallax_mas, 3), 'vel': round(v_tangential, 2),
|
|
|
|
| 309 |
'mse': round(mse_val, 6), 'kl': round(kl_val, 6),
|
| 310 |
'status': final_status, 'color': final_color,
|
| 311 |
'neighbors_js': js_neighbors_array,
|
|
|
|
| 347 |
state = st.session_state.session
|
| 348 |
if state['has_error']:
|
| 349 |
popup_html_component = f"""
|
| 350 |
+
<div id="pop-win" class="tactical-popup" style="border-color:#ff3333; border-radius:0px;">
|
| 351 |
<div class="pop-header"><span style="color:#ff3333">! ALERT_FAILURE</span><button onclick="document.getElementById('pop-win').style.display='none'" class="pop-close">×</button></div>
|
| 352 |
<div style="color:#ff3333;font-size:11px;text-align:center;padding:10px;font-weight:bold">{state['error_text']}</div>
|
| 353 |
</div>"""
|
| 354 |
elif state['data']:
|
| 355 |
sd = state['data']
|
| 356 |
popup_html_component = f"""
|
| 357 |
+
<div id="pop-win" class="tactical-popup" style="border-radius:0px;">
|
| 358 |
<div class="pop-header"><span>SADIM 77M // SCAN_REPORT</span><button onclick="document.getElementById('pop-win').style.display='none'" class="pop-close">×</button></div>
|
| 359 |
<div class="pop-section">
|
| 360 |
<div class="pop-row"><span>SOURCE_ID</span><b>{sd['id']}</b></div>
|
| 361 |
<div class="pop-row"><span>DIST_LY</span><b>{sd['dist']}</b></div>
|
| 362 |
+
<div class="pop-row"><span>PARALLAX</span><b>{sd['plx']} mas</b></div>
|
| 363 |
<div class="pop-row"><span>VEL_KMS (TAN)</span><b style="color:{'#ff3333' if sd['vel']>600 else '#ffffff'}">{sd['vel']}</b></div>
|
| 364 |
</div>
|
| 365 |
<div class="pop-section">
|
| 366 |
<div class="pop-row"><span>LOCAL NEIGHBORS</span><b>{sd['neighbor_count']} STARS</b></div>
|
|
|
|
| 367 |
</div>
|
| 368 |
<div class="pop-section-ai">
|
| 369 |
<div class="pop-row"><span>MSE_DEV</span><b>{sd['mse']}</b></div>
|
|
|
|
| 389 |
|
| 390 |
.tactical-popup {{
|
| 391 |
position: absolute; top: 25px; right: 25px; z-index: 9999;
|
| 392 |
+
background: rgba(10, 10, 10, 0.95); border: 1px solid #555;
|
| 393 |
+
padding: 15px; font-family: 'Courier New', Courier, monospace; width: 280px;
|
| 394 |
+
color: white; box-shadow: 0 10px 50px rgba(0,0,0,1);
|
| 395 |
}}
|
| 396 |
.pop-header {{
|
| 397 |
display: flex; justify-content: space-between; align-items: center;
|