Spaces:
Sleeping
Sleeping
devjas1
commited on
Commit
·
c8f5637
1
Parent(s):
df6f1ab
(FIX/UI): stabalize app.py — deprecation, sample-data run, layout jitter
Browse files- Replace deprecated 'st.image(use_column_width= ...)' with 'use_container_width=True'
- Fix 'Run Analysis' no-op after selecting Sample Data:
• Stop storing open file handles (StringIO) in 'session_state'
• Persist raw 'input_text' + 'filename' instead; compute inference ready from 'input_text'
• Add stable widget keys ('upload_txt','sample_select','run_btn')
- Reduce right-column reflow/jitter:
• 'use_container_width()' on plot image
• stable keys reduce tab-induced redraw instability
NOTES:
- No changes to model APIs or weights path logic.
- Keeps earlier portability improvements(Agg backend, dual import, 'logits.detach()') intact.'
app.py
CHANGED
@@ -107,7 +107,10 @@ def load_model(model_name):
|
|
107 |
# Load weights
|
108 |
state_dict = torch.load(model_path, map_location="cpu")
|
109 |
model.load_state_dict(state_dict, strict=False)
|
110 |
-
model
|
|
|
|
|
|
|
111 |
|
112 |
return model, True
|
113 |
|
@@ -205,7 +208,8 @@ def init_session_state():
|
|
205 |
defaults = {
|
206 |
'status_message': "Ready to analyze polymer spectra 🔬",
|
207 |
'status_type': "info",
|
208 |
-
'uploaded_file': None,
|
|
|
209 |
'filename': None,
|
210 |
'inference_run_once': False,
|
211 |
'x_raw': None,
|
@@ -278,36 +282,44 @@ def main():
|
|
278 |
uploaded_file = st.file_uploader(
|
279 |
"Upload Raman spectrum (.txt)",
|
280 |
type="txt",
|
281 |
-
help="Upload a text file with wavenumber and intensity columns"
|
|
|
282 |
)
|
283 |
|
284 |
if uploaded_file:
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
st.success(f"✅ Loaded: {uploaded_file.name}")
|
286 |
|
287 |
with tab2:
|
288 |
sample_files = get_sample_files()
|
289 |
if sample_files:
|
290 |
sample_options = ["-- Select Sample --"] + [f.name for f in sample_files]
|
291 |
-
selected_sample = st.selectbox("Choose sample spectrum:", sample_options)
|
292 |
|
293 |
if selected_sample != "-- Select Sample --":
|
294 |
selected_path = Path(SAMPLE_DATA_DIR) / selected_sample
|
295 |
try:
|
296 |
with open(selected_path, "r", encoding="utf-8") as f:
|
297 |
file_contents = f.read()
|
298 |
-
|
299 |
-
|
|
|
|
|
300 |
st.success(f"✅ Loaded sample: {selected_sample}")
|
301 |
-
except
|
302 |
st.error(f"Error loading sample: {e}")
|
303 |
else:
|
304 |
st.info("No sample data available")
|
305 |
|
306 |
# Update session state
|
307 |
-
|
308 |
-
|
309 |
-
st.session_state['
|
310 |
-
st.session_state['status_message'] = f"📁 File '{uploaded_file.name}' ready for analysis"
|
311 |
st.session_state['status_type'] = "success"
|
312 |
|
313 |
# Status display
|
@@ -325,27 +337,20 @@ def main():
|
|
325 |
# Load model
|
326 |
model, model_loaded = load_model(model_choice)
|
327 |
|
328 |
-
#
|
329 |
-
inference_ready = (
|
330 |
-
'uploaded_file' in st.session_state and
|
331 |
-
st.session_state['uploaded_file'] is not None and
|
332 |
-
model is not None
|
333 |
-
)
|
334 |
|
335 |
if not model_loaded:
|
336 |
st.warning("⚠️ Model weights not available - using demo mode")
|
337 |
|
338 |
-
if st.button("▶️ Run Analysis", disabled=not inference_ready, type="primary"):
|
339 |
if inference_ready:
|
340 |
try:
|
341 |
-
#
|
342 |
-
|
343 |
-
filename = st.session_state
|
344 |
-
|
345 |
-
|
346 |
-
uploaded_file.seek(0)
|
347 |
-
raw_data = uploaded_file.read()
|
348 |
-
raw_text = raw_data.decode("utf-8") if isinstance(raw_data, bytes) else raw_data
|
349 |
|
350 |
# Parse spectrum
|
351 |
with st.spinner("Parsing spectrum data..."):
|
@@ -386,7 +391,7 @@ def main():
|
|
386 |
# Create and display plot
|
387 |
try:
|
388 |
spectrum_plot = create_spectrum_plot(x_raw, y_raw, y_resampled)
|
389 |
-
st.image(spectrum_plot, caption="Spectrum Preprocessing Results",
|
390 |
except Exception as e:
|
391 |
st.warning(f"Could not generate plot: {e}")
|
392 |
|
@@ -462,10 +467,10 @@ def main():
|
|
462 |
|
463 |
st.markdown("**Spectrum Statistics**")
|
464 |
st.json({
|
465 |
-
"Original Length": len(x_raw),
|
466 |
"Resampled Length": TARGET_LEN,
|
467 |
-
"Wavenumber Range": f"{min(x_raw):.1f} - {max(x_raw):.1f} cm⁻¹",
|
468 |
-
"Intensity Range": f"{min(y_raw):.1f} - {max(y_raw):.1f}",
|
469 |
"Model Confidence": confidence_desc
|
470 |
})
|
471 |
|
|
|
107 |
# Load weights
|
108 |
state_dict = torch.load(model_path, map_location="cpu")
|
109 |
model.load_state_dict(state_dict, strict=False)
|
110 |
+
if model is not None:
|
111 |
+
model.eval()
|
112 |
+
else:
|
113 |
+
raise ValueError("Model is not loaded. Please check the model configuration or weights.")
|
114 |
|
115 |
return model, True
|
116 |
|
|
|
208 |
defaults = {
|
209 |
'status_message': "Ready to analyze polymer spectra 🔬",
|
210 |
'status_type': "info",
|
211 |
+
'uploaded_file': None, # legacy; kept for compatibility
|
212 |
+
'input_text': None, # ←←← NEW: canonical store for spectrum text
|
213 |
'filename': None,
|
214 |
'inference_run_once': False,
|
215 |
'x_raw': None,
|
|
|
282 |
uploaded_file = st.file_uploader(
|
283 |
"Upload Raman spectrum (.txt)",
|
284 |
type="txt",
|
285 |
+
help="Upload a text file with wavenumber and intensity columns",
|
286 |
+
key="upload_text"
|
287 |
)
|
288 |
|
289 |
if uploaded_file:
|
290 |
+
# Read now and persist raw text; avoid holding open buffers in session_state
|
291 |
+
raw = uploaded_file.read()
|
292 |
+
text = raw.decode("utf-8") if isinstance(raw, bytes) else raw
|
293 |
+
st.session_state['input_text'] = text
|
294 |
+
st.session_state['filename'] = uploaded_file.name
|
295 |
+
st.session_state['uploaded_file'] = None # avoid stale buffers
|
296 |
st.success(f"✅ Loaded: {uploaded_file.name}")
|
297 |
|
298 |
with tab2:
|
299 |
sample_files = get_sample_files()
|
300 |
if sample_files:
|
301 |
sample_options = ["-- Select Sample --"] + [f.name for f in sample_files]
|
302 |
+
selected_sample = st.selectbox("Choose sample spectrum:", sample_options, key="sample_select")
|
303 |
|
304 |
if selected_sample != "-- Select Sample --":
|
305 |
selected_path = Path(SAMPLE_DATA_DIR) / selected_sample
|
306 |
try:
|
307 |
with open(selected_path, "r", encoding="utf-8") as f:
|
308 |
file_contents = f.read()
|
309 |
+
# Persist raw text + name; no open file handles in session_state
|
310 |
+
st.session_state['input_text'] = file_contents
|
311 |
+
st.session_state['filename'] = selected_sample
|
312 |
+
st.session_state['uploaded_file'] = None
|
313 |
st.success(f"✅ Loaded sample: {selected_sample}")
|
314 |
+
except (FileNotFoundError, IOError) as e:
|
315 |
st.error(f"Error loading sample: {e}")
|
316 |
else:
|
317 |
st.info("No sample data available")
|
318 |
|
319 |
# Update session state
|
320 |
+
# If we captured text via either tab, reflect readiness in status
|
321 |
+
if st.session_state.get('input_text'):
|
322 |
+
st.session_state['status_message'] = f"📁 File '{st.session_state.get('filename', '(unnamed)')}' ready for analysis"
|
|
|
323 |
st.session_state['status_type'] = "success"
|
324 |
|
325 |
# Status display
|
|
|
337 |
# Load model
|
338 |
model, model_loaded = load_model(model_choice)
|
339 |
|
340 |
+
# Ready if we have cached text and a model instance
|
341 |
+
inference_ready = bool(st.session_state.get('input_text')) and (model is not None)
|
|
|
|
|
|
|
|
|
342 |
|
343 |
if not model_loaded:
|
344 |
st.warning("⚠️ Model weights not available - using demo mode")
|
345 |
|
346 |
+
if st.button("▶️ Run Analysis", disabled=not inference_ready, type="primary", key="run_btn"):
|
347 |
if inference_ready:
|
348 |
try:
|
349 |
+
# Use persisted text + filename (works for uploads and samples)
|
350 |
+
raw_text = st.session_state.get('input_text')
|
351 |
+
filename = st.session_state.get('filename') or "unknown.txt"
|
352 |
+
if not raw_text:
|
353 |
+
raise ValueError("No input text available. Please upload or select a sample.")
|
|
|
|
|
|
|
354 |
|
355 |
# Parse spectrum
|
356 |
with st.spinner("Parsing spectrum data..."):
|
|
|
391 |
# Create and display plot
|
392 |
try:
|
393 |
spectrum_plot = create_spectrum_plot(x_raw, y_raw, y_resampled)
|
394 |
+
st.image(spectrum_plot, caption="Spectrum Preprocessing Results", use_container_width=True)
|
395 |
except Exception as e:
|
396 |
st.warning(f"Could not generate plot: {e}")
|
397 |
|
|
|
467 |
|
468 |
st.markdown("**Spectrum Statistics**")
|
469 |
st.json({
|
470 |
+
"Original Length": len(x_raw) if x_raw is not None else 0,
|
471 |
"Resampled Length": TARGET_LEN,
|
472 |
+
"Wavenumber Range": f"{min(x_raw):.1f} - {max(x_raw):.1f} cm⁻¹" if x_raw is not None else "N/A",
|
473 |
+
"Intensity Range": f"{min(y_raw):.1f} - {max(y_raw):.1f}" if y_raw is not None else "N/A",
|
474 |
"Model Confidence": confidence_desc
|
475 |
})
|
476 |
|