Spaces:
Sleeping
Sleeping
devjas1
commited on
Commit
·
8c75a82
1
Parent(s):
2547be1
fix(results): Improve formatting and consistency in results management functions
Browse files- utils/results_manager.py +52 -24
utils/results_manager.py
CHANGED
|
@@ -31,7 +31,7 @@ class ResultsManager:
|
|
| 31 |
logits: List[float],
|
| 32 |
ground_truth: Optional[int] = None,
|
| 33 |
processing_time: float = 0.0,
|
| 34 |
-
metadata: Optional[Dict[str, Any]] = None
|
| 35 |
) -> None:
|
| 36 |
"""Add a single inference result to the results table"""
|
| 37 |
ResultsManager.init_results_table()
|
|
@@ -46,7 +46,7 @@ class ResultsManager:
|
|
| 46 |
"logits": logits,
|
| 47 |
"ground_truth": ground_truth,
|
| 48 |
"processing_time": processing_time,
|
| 49 |
-
"metadata": metadata or {}
|
| 50 |
}
|
| 51 |
|
| 52 |
st.session_state[ResultsManager.RESULTS_KEY].append(result)
|
|
@@ -84,9 +84,17 @@ class ResultsManager:
|
|
| 84 |
"Prediction": result["prediction"],
|
| 85 |
"Predicted Class": result["predicted_class"],
|
| 86 |
"Confidence": f"{result['confidence']:.3f}",
|
| 87 |
-
"Stable Logit":
|
| 88 |
-
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
"Processing Time (s)": f"{result['processing_time']:.3f}",
|
| 91 |
}
|
| 92 |
df_data.append(row)
|
|
@@ -103,7 +111,7 @@ class ResultsManager:
|
|
| 103 |
# ===Use StringIO to create CSV in memory===
|
| 104 |
csv_buffer = io.StringIO()
|
| 105 |
df.to_csv(csv_buffer, index=False)
|
| 106 |
-
return csv_buffer.getvalue().encode(
|
| 107 |
|
| 108 |
@staticmethod
|
| 109 |
def export_to_json() -> str:
|
|
@@ -126,12 +134,16 @@ class ResultsManager:
|
|
| 126 |
"stable_predictions": sum(1 for r in results if r["prediction"] == 0),
|
| 127 |
"weathered_predictions": sum(1 for r in results if r["prediction"] == 1),
|
| 128 |
"avg_confidence": sum(r["confidence"] for r in results) / len(results),
|
| 129 |
-
"avg_processing_time": sum(r["processing_time"] for r in results)
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
| 131 |
}
|
| 132 |
# ===Calculate accuracy if ground truth is available===
|
| 133 |
correct_predictions = sum(
|
| 134 |
-
1
|
|
|
|
| 135 |
if r["ground_truth"] is not None and r["prediction"] == r["ground_truth"]
|
| 136 |
)
|
| 137 |
total_with_gt = stats["files_with_ground_truth"]
|
|
@@ -164,11 +176,13 @@ class ResultsManager:
|
|
| 164 |
"status_type": "info",
|
| 165 |
"input_text": None,
|
| 166 |
"filename": None,
|
| 167 |
-
"input_source": None,
|
| 168 |
"sample_select": "-- Select Sample --",
|
| 169 |
-
"input_mode": "Upload File",
|
| 170 |
"inference_run_once": False,
|
| 171 |
-
"x_raw": None,
|
|
|
|
|
|
|
| 172 |
"log_messages": [],
|
| 173 |
"uploader_version": 0,
|
| 174 |
"current_upload_key": "upload_txt_0",
|
|
@@ -184,6 +198,9 @@ class ResultsManager:
|
|
| 184 |
@staticmethod
|
| 185 |
def reset_ephemeral_state():
|
| 186 |
"""Comprehensive reset for the entire app state."""
|
|
|
|
|
|
|
|
|
|
| 187 |
# Define keys that should NOT be cleared by a full reset
|
| 188 |
keep_keys = {"model_select", "input_mode"}
|
| 189 |
|
|
@@ -191,12 +208,17 @@ class ResultsManager:
|
|
| 191 |
if k not in keep_keys:
|
| 192 |
st.session_state.pop(k, None)
|
| 193 |
|
| 194 |
-
|
| 195 |
-
|
|
|
|
|
|
|
|
|
|
| 196 |
|
| 197 |
-
# CRITICAL:
|
| 198 |
-
st.session_state["uploader_version"]
|
| 199 |
-
st.session_state["current_upload_key"] =
|
|
|
|
|
|
|
| 200 |
|
| 201 |
@staticmethod
|
| 202 |
def display_results_table() -> None:
|
|
@@ -205,7 +227,8 @@ class ResultsManager:
|
|
| 205 |
|
| 206 |
if df.empty:
|
| 207 |
st.info(
|
| 208 |
-
"No inference results yet. Upload files and run analysis to see results here."
|
|
|
|
| 209 |
return
|
| 210 |
|
| 211 |
st.subheader(f"Inference Results ({len(df)} files)")
|
|
@@ -220,7 +243,9 @@ class ResultsManager:
|
|
| 220 |
st.metric("Avg Confidence", f"{stats['avg_confidence']:.3f}")
|
| 221 |
with col3:
|
| 222 |
st.metric(
|
| 223 |
-
"Stable/Weathered",
|
|
|
|
|
|
|
| 224 |
with col4:
|
| 225 |
if stats["accuracy"] is not None:
|
| 226 |
st.metric("Accuracy", f"{stats['accuracy']:.3f}")
|
|
@@ -231,7 +256,7 @@ class ResultsManager:
|
|
| 231 |
st.dataframe(df, use_container_width=True)
|
| 232 |
|
| 233 |
# ==Export Button==
|
| 234 |
-
col1, col2, col3 = st.columns([1, 1,
|
| 235 |
|
| 236 |
with col1:
|
| 237 |
csv_data = ResultsManager.export_to_csv()
|
|
@@ -240,7 +265,7 @@ class ResultsManager:
|
|
| 240 |
label="Download CSV",
|
| 241 |
data=csv_data,
|
| 242 |
file_name=f"polymer_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
|
| 243 |
-
mime="text/csv"
|
| 244 |
)
|
| 245 |
|
| 246 |
with col2:
|
|
@@ -250,9 +275,12 @@ class ResultsManager:
|
|
| 250 |
label="📥 Download JSON",
|
| 251 |
data=json_data,
|
| 252 |
file_name=f"polymer_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
|
| 253 |
-
mime="application/json"
|
| 254 |
)
|
| 255 |
|
| 256 |
with col3:
|
| 257 |
-
|
| 258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
logits: List[float],
|
| 32 |
ground_truth: Optional[int] = None,
|
| 33 |
processing_time: float = 0.0,
|
| 34 |
+
metadata: Optional[Dict[str, Any]] = None,
|
| 35 |
) -> None:
|
| 36 |
"""Add a single inference result to the results table"""
|
| 37 |
ResultsManager.init_results_table()
|
|
|
|
| 46 |
"logits": logits,
|
| 47 |
"ground_truth": ground_truth,
|
| 48 |
"processing_time": processing_time,
|
| 49 |
+
"metadata": metadata or {},
|
| 50 |
}
|
| 51 |
|
| 52 |
st.session_state[ResultsManager.RESULTS_KEY].append(result)
|
|
|
|
| 84 |
"Prediction": result["prediction"],
|
| 85 |
"Predicted Class": result["predicted_class"],
|
| 86 |
"Confidence": f"{result['confidence']:.3f}",
|
| 87 |
+
"Stable Logit": (
|
| 88 |
+
f"{result['logits'][0]:.3f}" if len(result["logits"]) > 0 else "N/A"
|
| 89 |
+
),
|
| 90 |
+
"Weathered Logit": (
|
| 91 |
+
f"{result['logits'][1]:.3f}" if len(result["logits"]) > 1 else "N/A"
|
| 92 |
+
),
|
| 93 |
+
"Ground Truth": (
|
| 94 |
+
result["ground_truth"]
|
| 95 |
+
if result["ground_truth"] is not None
|
| 96 |
+
else "Unknown"
|
| 97 |
+
),
|
| 98 |
"Processing Time (s)": f"{result['processing_time']:.3f}",
|
| 99 |
}
|
| 100 |
df_data.append(row)
|
|
|
|
| 111 |
# ===Use StringIO to create CSV in memory===
|
| 112 |
csv_buffer = io.StringIO()
|
| 113 |
df.to_csv(csv_buffer, index=False)
|
| 114 |
+
return csv_buffer.getvalue().encode("utf-8")
|
| 115 |
|
| 116 |
@staticmethod
|
| 117 |
def export_to_json() -> str:
|
|
|
|
| 134 |
"stable_predictions": sum(1 for r in results if r["prediction"] == 0),
|
| 135 |
"weathered_predictions": sum(1 for r in results if r["prediction"] == 1),
|
| 136 |
"avg_confidence": sum(r["confidence"] for r in results) / len(results),
|
| 137 |
+
"avg_processing_time": sum(r["processing_time"] for r in results)
|
| 138 |
+
/ len(results),
|
| 139 |
+
"files_with_ground_truth": sum(
|
| 140 |
+
1 for r in results if r["ground_truth"] is not None
|
| 141 |
+
),
|
| 142 |
}
|
| 143 |
# ===Calculate accuracy if ground truth is available===
|
| 144 |
correct_predictions = sum(
|
| 145 |
+
1
|
| 146 |
+
for r in results
|
| 147 |
if r["ground_truth"] is not None and r["prediction"] == r["ground_truth"]
|
| 148 |
)
|
| 149 |
total_with_gt = stats["files_with_ground_truth"]
|
|
|
|
| 176 |
"status_type": "info",
|
| 177 |
"input_text": None,
|
| 178 |
"filename": None,
|
| 179 |
+
"input_source": None, # "upload", "batch" or "sample"
|
| 180 |
"sample_select": "-- Select Sample --",
|
| 181 |
+
"input_mode": "Upload File", # controls which pane is visible
|
| 182 |
"inference_run_once": False,
|
| 183 |
+
"x_raw": None,
|
| 184 |
+
"y_raw": None,
|
| 185 |
+
"y_resampled": None,
|
| 186 |
"log_messages": [],
|
| 187 |
"uploader_version": 0,
|
| 188 |
"current_upload_key": "upload_txt_0",
|
|
|
|
| 198 |
@staticmethod
|
| 199 |
def reset_ephemeral_state():
|
| 200 |
"""Comprehensive reset for the entire app state."""
|
| 201 |
+
|
| 202 |
+
current_version = st.session_state.get("uploader_version", 0)
|
| 203 |
+
|
| 204 |
# Define keys that should NOT be cleared by a full reset
|
| 205 |
keep_keys = {"model_select", "input_mode"}
|
| 206 |
|
|
|
|
| 208 |
if k not in keep_keys:
|
| 209 |
st.session_state.pop(k, None)
|
| 210 |
|
| 211 |
+
st.session_state["status_message"] = "Ready to analyze polymer spectra"
|
| 212 |
+
st.session_state["status_type"] = "info"
|
| 213 |
+
st.session_state["batch_files"] = []
|
| 214 |
+
st.session_state["inference_run_once"] = True
|
| 215 |
+
st.session_state[""] = ""
|
| 216 |
|
| 217 |
+
# CRITICAL: Increment the preserved version and re-assign it
|
| 218 |
+
st.session_state["uploader_version"] = current_version + 1
|
| 219 |
+
st.session_state["current_upload_key"] = (
|
| 220 |
+
f"upload_txt_{st.session_state['uploader_version']}"
|
| 221 |
+
)
|
| 222 |
|
| 223 |
@staticmethod
|
| 224 |
def display_results_table() -> None:
|
|
|
|
| 227 |
|
| 228 |
if df.empty:
|
| 229 |
st.info(
|
| 230 |
+
"No inference results yet. Upload files and run analysis to see results here."
|
| 231 |
+
)
|
| 232 |
return
|
| 233 |
|
| 234 |
st.subheader(f"Inference Results ({len(df)} files)")
|
|
|
|
| 243 |
st.metric("Avg Confidence", f"{stats['avg_confidence']:.3f}")
|
| 244 |
with col3:
|
| 245 |
st.metric(
|
| 246 |
+
"Stable/Weathered",
|
| 247 |
+
f"{stats['stable_predictions']}/{stats['weathered_predictions']}",
|
| 248 |
+
)
|
| 249 |
with col4:
|
| 250 |
if stats["accuracy"] is not None:
|
| 251 |
st.metric("Accuracy", f"{stats['accuracy']:.3f}")
|
|
|
|
| 256 |
st.dataframe(df, use_container_width=True)
|
| 257 |
|
| 258 |
# ==Export Button==
|
| 259 |
+
col1, col2, col3 = st.columns([1, 1, 1])
|
| 260 |
|
| 261 |
with col1:
|
| 262 |
csv_data = ResultsManager.export_to_csv()
|
|
|
|
| 265 |
label="Download CSV",
|
| 266 |
data=csv_data,
|
| 267 |
file_name=f"polymer_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
|
| 268 |
+
mime="text/csv",
|
| 269 |
)
|
| 270 |
|
| 271 |
with col2:
|
|
|
|
| 275 |
label="📥 Download JSON",
|
| 276 |
data=json_data,
|
| 277 |
file_name=f"polymer_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
|
| 278 |
+
mime="application/json",
|
| 279 |
)
|
| 280 |
|
| 281 |
with col3:
|
| 282 |
+
st.button(
|
| 283 |
+
"Clear All Results",
|
| 284 |
+
help="Clear all stored results",
|
| 285 |
+
on_click=ResultsManager.reset_ephemeral_state,
|
| 286 |
+
)
|