Spaces:
Sleeping
Sleeping
File size: 5,987 Bytes
486ca74 f0ce95f 486ca74 fc07d9f f0ce95f 486ca74 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import os
import streamlit as st
from dotenv import load_dotenv
from model_loader import load_mitbih_model, load_pcg_model, load_emg_model, load_vag_model
from chatbot import analyze_signal
from util import analyze_pcg_signal, analyze_emg_signal, predict_vag_from_features,vag_to_features
load_dotenv()
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY", "")
st.set_page_config(page_title="Biosignal Chatbot", page_icon="🩺", layout="centered")
st.title("🩺 Biosignal Diagnostic Chatbot")
MODELS = {
"ECG": load_mitbih_model(),
"PCG": load_pcg_model(),
"EMG": load_emg_model(),
"VAG": load_vag_model(),
}
FILE_TYPES = {
"ECG": ["csv", "txt"],
"EMG": ["csv", "txt"],
"VAG": ["csv", "npy", "wav"],
"PCG": ["wav"],
}
tabs = st.tabs(["ECG", "EMG", "VAG", "PCG"])
for tab, sig in zip(tabs, ["ECG", "EMG", "VAG", "PCG"]):
with tab:
st.header(f"{sig} Analysis")
if sig == "ECG":
with st.expander("📄 ECG Data Requirements"):
st.markdown(
"- Upload a `.csv` or `.txt` file containing **256 numeric values** (single row or single column).\n"
"- Example:\n"
"```csv\n0.12\n0.15\n-0.05\n...\n```"
)
elif sig == "VAG":
with st.expander("📄 VAG Data Requirements"):
st.markdown(
"- Upload a `.csv` file **with headers** containing the following 5 features:\n"
" - `rms_amplitude`\n"
" - `peak_frequency`\n"
" - `spectral_entropy`\n"
" - `zero_crossing_rate`\n"
" - `mean_frequency`\n"
"- Example file content:\n"
"```csv\n"
"rms_amplitude,peak_frequency,spectral_entropy,zero_crossing_rate,mean_frequency\n"
"1.02,20,-1890.34,0.001,39.7\n"
"```"
)
elif sig == "EMG":
with st.expander("📄 EMG Data Requirements"):
st.markdown(
"- Upload a `.txt` or `.csv` file containing **raw EMG signal samples**.\n"
"- The model expects **at least 1,000 values** (1-second window at 1 kHz sampling).\n"
"- You can provide:\n"
" - A `.txt` file with one value per line.\n"
" - A `.csv` file with a single column of numbers.\n\n"
"- Example `.txt` file:\n"
"```txt\n"
"0.034\n"
"0.056\n"
"-0.012\n"
"...\n"
"```"
)
elif sig == "PCG":
with st.expander("📄 PCG Data Requirements"):
st.markdown(
"- Upload a `.wav` file containing a **single-channel (mono) PCG signal**.\n"
"- The model expects **at least 995 audio samples** (≈0.025s of heart sound at 44.1 kHz).\n"
"- Files longer than 995 samples will be **trimmed**; shorter ones will be **zero-padded**.\n"
"- Ensure the signal is **clean and preprocessed** (no ambient noise).\n\n"
"- Example `.wav` properties:\n"
" - Mono (1 channel)\n"
" - 44.1 kHz sampling rate\n"
" - 16-bit PCM or float32\n"
"\n"
"_Note: Do not upload `.mp3`, `.flac`, or stereo files—they may fail to process properly._"
)
uploaded = st.file_uploader(
f"Upload {sig} file",
type=FILE_TYPES[sig],
key=f"upload_{sig}"
)
if sig == "ECG" and uploaded and st.button("Run Diagnostic", key=f"run_{sig}"):
label, human, conf, gnote = analyze_signal(
uploaded, MODELS["ECG"], GEMINI_API_KEY, signal_type="ECG"
)
st.success(f"**{label} – {human}**\n\nConfidence: {conf:.2%}")
if gnote:
st.markdown("### 🧠 Gemini Insight")
st.write(gnote)
elif not GEMINI_API_KEY:
st.info("Gemini key missing – no explanation.")
elif sig == "PCG" and uploaded and st.button("Run Diagnostic", key=f"run_{sig}"):
label, human, conf, gnote = analyze_pcg_signal(
uploaded, MODELS["PCG"], GEMINI_API_KEY
)
st.success(f"**{label}**\n\nConfidence: {conf:.2%}")
if gnote:
st.markdown("### 🧠 Gemini Insight")
st.write(gnote)
elif not GEMINI_API_KEY:
st.info("Gemini key missing – no explanation.")
elif sig == "EMG" and uploaded and st.button("Run Diagnostic", key=f"run_{sig}"):
human, conf, gnote = analyze_emg_signal(
uploaded, MODELS["EMG"], GEMINI_API_KEY
)
st.success(f"**{human.upper()}**\n\nConfidence: {conf:.2%}")
if gnote:
st.markdown("### 🧠 Gemini Insight")
st.write(gnote)
elif not GEMINI_API_KEY:
st.info("Gemini key missing – no explanation.")
elif sig == "VAG" and uploaded and st.button("Run Diagnostic", key=f"run_{sig}"):
label, human, conf, gnote = predict_vag_from_features(
uploaded, MODELS["VAG"], GEMINI_API_KEY
)
st.success(f"**{label}**\n\nConfidence: {conf:.2%}")
if gnote:
st.markdown("### 🧠 Gemini Insight")
st.write(gnote)
elif not GEMINI_API_KEY:
st.info("Gemini key missing – no explanation.")
else:
if not uploaded:
st.info("Upload a file to begin.")
st.caption("© 2025 Biosignal Chatbot")
|