Spaces:
Runtime error
Runtime error
Upload app.py
Browse files
app.py
CHANGED
|
@@ -16,7 +16,6 @@ audio + parsed metadata (viral loads default to 0) and show "not available" trut
|
|
| 16 |
import os
|
| 17 |
import json
|
| 18 |
import numpy as np
|
| 19 |
-
import pandas as pd
|
| 20 |
import joblib
|
| 21 |
import gradio as gr
|
| 22 |
|
|
@@ -38,10 +37,31 @@ LUT = xl.build_lookup(XLSX) # ground truth + viral loads fr
|
|
| 38 |
FE, AST, AST_DEV = ae.load_ast() # AST weights download on first run
|
| 39 |
|
| 40 |
LBL = {"S": "Survivor (S)", "T": "Terminal (T)"}
|
| 41 |
-
|
| 42 |
-
"
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
|
| 47 |
def _predict_one(path):
|
|
@@ -77,7 +97,7 @@ def _predict_one(path):
|
|
| 77 |
|
| 78 |
def predict_batch(files, progress=gr.Progress()):
|
| 79 |
if not files:
|
| 80 |
-
return
|
| 81 |
paths = [f if isinstance(f, str) else f.name for f in files]
|
| 82 |
rows = []
|
| 83 |
for p in progress.tqdm(paths, desc="Scoring recordings"):
|
|
@@ -86,28 +106,23 @@ def predict_batch(files, progress=gr.Progress()):
|
|
| 86 |
except Exception as e: # noqa
|
| 87 |
rows.append([os.path.basename(p), "?", "?", "?", "",
|
| 88 |
"error", str(e)[:30], "error", "", "β"])
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
return df, summary
|
| 95 |
|
| 96 |
|
| 97 |
CSS = """
|
| 98 |
.gradio-container {background:#ffffff !important; color:#000000 !important;
|
| 99 |
font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; max-width:1150px;}
|
| 100 |
.gradio-container * {color:#000000;}
|
| 101 |
-
h1,h2,h3,p,
|
| 102 |
button.primary, .primary {background:#000000 !important; color:#ffffff !important;
|
| 103 |
border:1px solid #000000 !important; border-radius:6px !important;}
|
| 104 |
button.primary:hover, .primary:hover {background:#222222 !important;}
|
|
|
|
| 105 |
.secondary {background:#ffffff !important; color:#000000 !important; border:1px solid #000000 !important;}
|
| 106 |
-
table {border-collapse:collapse !important;}
|
| 107 |
-
th {background:#f5f5f5 !important; color:#000000 !important; font-weight:600 !important;
|
| 108 |
-
white-space:nowrap !important; text-overflow:clip !important;}
|
| 109 |
-
td,th {border:1px solid #dddddd !important; padding:6px 10px !important; color:#000000 !important;
|
| 110 |
-
overflow-wrap:anywhere;}
|
| 111 |
footer {display:none !important;}
|
| 112 |
"""
|
| 113 |
THEME = gr.themes.Base(primary_hue=gr.themes.colors.gray,
|
|
@@ -134,8 +149,8 @@ with gr.Blocks(title="Bee Colony Survival β Multimodal Predictor", theme=THEME
|
|
| 134 |
btn = gr.Button("Predict", variant="primary")
|
| 135 |
clear = gr.Button("Clear", variant="secondary")
|
| 136 |
summary = gr.Markdown()
|
| 137 |
-
|
| 138 |
-
|
| 139 |
if example_files:
|
| 140 |
gr.Markdown("**Example recordings** β click any one to load it and run the prediction "
|
| 141 |
"(all are Terminal colonies the model correctly detects). "
|
|
@@ -151,8 +166,7 @@ with gr.Blocks(title="Bee Colony Survival β Multimodal Predictor", theme=THEME
|
|
| 151 |
label="Bundled examples",
|
| 152 |
)
|
| 153 |
btn.click(predict_batch, inputs=audio_in, outputs=[table, summary])
|
| 154 |
-
clear.click(lambda: (None,
|
| 155 |
-
outputs=[audio_in, table, summary])
|
| 156 |
|
| 157 |
if __name__ == "__main__":
|
| 158 |
demo.launch()
|
|
|
|
| 16 |
import os
|
| 17 |
import json
|
| 18 |
import numpy as np
|
|
|
|
| 19 |
import joblib
|
| 20 |
import gradio as gr
|
| 21 |
|
|
|
|
| 37 |
FE, AST, AST_DEV = ae.load_ast() # AST weights download on first run
|
| 38 |
|
| 39 |
LBL = {"S": "Survivor (S)", "T": "Terminal (T)"}
|
| 40 |
+
HEADERS = ["File", "Colony", "Country", "Month", "Viral CBPV / DWV / KBV",
|
| 41 |
+
"Predicted 0β3", "Actual 0β3", "Predicted 4β6", "Actual 4β6", "Match"]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def _results_html(rows):
|
| 45 |
+
"""Render results as a self-styled HTML table (full control, no truncation)."""
|
| 46 |
+
th = "".join(
|
| 47 |
+
f'<th style="border:1px solid #e3e3e3;padding:9px 14px;background:#f4f4f4;'
|
| 48 |
+
f'color:#000;font-weight:600;text-align:left;white-space:nowrap;">{h}</th>'
|
| 49 |
+
for h in HEADERS)
|
| 50 |
+
trs = []
|
| 51 |
+
for r in rows:
|
| 52 |
+
tds = []
|
| 53 |
+
for i, v in enumerate(r):
|
| 54 |
+
extra = "white-space:nowrap;"
|
| 55 |
+
if HEADERS[i] == "Match":
|
| 56 |
+
c = {"β": "#157347", "β": "#b42318"}.get(v, "#888")
|
| 57 |
+
extra += f"text-align:center;font-weight:700;font-size:16px;color:{c};"
|
| 58 |
+
tds.append(f'<td style="border:1px solid #e3e3e3;padding:9px 14px;color:#000;'
|
| 59 |
+
f'{extra}">{v}</td>')
|
| 60 |
+
trs.append("<tr>" + "".join(tds) + "</tr>")
|
| 61 |
+
return ('<div style="overflow-x:auto;width:100%;">'
|
| 62 |
+
'<table style="border-collapse:collapse;background:#fff;color:#000;'
|
| 63 |
+
'font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:14px;">'
|
| 64 |
+
f'<thead><tr>{th}</tr></thead><tbody>{"".join(trs)}</tbody></table></div>')
|
| 65 |
|
| 66 |
|
| 67 |
def _predict_one(path):
|
|
|
|
| 97 |
|
| 98 |
def predict_batch(files, progress=gr.Progress()):
|
| 99 |
if not files:
|
| 100 |
+
return "", "Upload one or more `.wav` files (or click an example), then press **Predict**."
|
| 101 |
paths = [f if isinstance(f, str) else f.name for f in files]
|
| 102 |
rows = []
|
| 103 |
for p in progress.tqdm(paths, desc="Scoring recordings"):
|
|
|
|
| 106 |
except Exception as e: # noqa
|
| 107 |
rows.append([os.path.basename(p), "?", "?", "?", "",
|
| 108 |
"error", str(e)[:30], "error", "", "β"])
|
| 109 |
+
n_known = sum(1 for r in rows if r[9] != "β")
|
| 110 |
+
n_ok = sum(1 for r in rows if r[9] == "β")
|
| 111 |
+
summary = (f"Scored **{len(rows)}** file(s) Β· **{n_known}** found in the Excel workbook "
|
| 112 |
+
f"Β· **{n_ok}/{n_known}** predicted correctly (both horizons).")
|
| 113 |
+
return _results_html(rows), summary
|
|
|
|
| 114 |
|
| 115 |
|
| 116 |
CSS = """
|
| 117 |
.gradio-container {background:#ffffff !important; color:#000000 !important;
|
| 118 |
font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; max-width:1150px;}
|
| 119 |
.gradio-container * {color:#000000;}
|
| 120 |
+
h1,h2,h3,p,label {color:#000000 !important;}
|
| 121 |
button.primary, .primary {background:#000000 !important; color:#ffffff !important;
|
| 122 |
border:1px solid #000000 !important; border-radius:6px !important;}
|
| 123 |
button.primary:hover, .primary:hover {background:#222222 !important;}
|
| 124 |
+
button.primary *, .primary * {color:#ffffff !important;}
|
| 125 |
.secondary {background:#ffffff !important; color:#000000 !important; border:1px solid #000000 !important;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
footer {display:none !important;}
|
| 127 |
"""
|
| 128 |
THEME = gr.themes.Base(primary_hue=gr.themes.colors.gray,
|
|
|
|
| 149 |
btn = gr.Button("Predict", variant="primary")
|
| 150 |
clear = gr.Button("Clear", variant="secondary")
|
| 151 |
summary = gr.Markdown()
|
| 152 |
+
gr.Markdown("### Results")
|
| 153 |
+
table = gr.HTML()
|
| 154 |
if example_files:
|
| 155 |
gr.Markdown("**Example recordings** β click any one to load it and run the prediction "
|
| 156 |
"(all are Terminal colonies the model correctly detects). "
|
|
|
|
| 166 |
label="Bundled examples",
|
| 167 |
)
|
| 168 |
btn.click(predict_batch, inputs=audio_in, outputs=[table, summary])
|
| 169 |
+
clear.click(lambda: (None, "", ""), outputs=[audio_in, table, summary])
|
|
|
|
| 170 |
|
| 171 |
if __name__ == "__main__":
|
| 172 |
demo.launch()
|