Demential_Classification / app_AD2class.py
KeenWoo's picture
Update app_AD2class.py
9e7cbce verified
# app_AD2class.py
# Main application file. Builds a tabbed Gradio UI for multiple assessments.
import gradio as gr
# Import the separated modules
import MMSE
import CDRM # <-- Import the new placeholder module
import utils
# --- MMSE UI and Logic ---
def build_mmse_tab(mmse_score_state):
"""Builds the UI components for the MMSE tab."""
with gr.Blocks() as mmse_tab:
gr.Markdown("## Mini Mental State Exam")
question_index = gr.State(0)
answers = gr.State([""] * MMSE.TOTAL_QUESTIONS)
jump_nav = gr.Dropdown(choices=MMSE.QUESTION_CHOICES, value=MMSE.QUESTION_CHOICES[0], label="Jump to Question")
initial_q = MMSE.STRUCTURED_QUESTIONS[0]
progress_text = gr.Markdown(f"## {initial_q['main_cat']} - Q{initial_q['main_num']}{initial_q['sub_letter']} ({1} of {MMSE.TOTAL_QUESTIONS})")
instruction_display = gr.Markdown(initial_q["instruction"])
question_button = gr.Button(f"Say πŸ”Š {initial_q['question']}", variant="secondary")
with gr.Group():
answer_text = gr.Textbox(label="Your Answer (type or record below)")
audio_input = gr.Audio(sources=["microphone"], label="🎀 Record Your Answer Here")
image_upload = gr.Image(type="filepath", label="Upload Drawing for Drawing Question", visible=(initial_q['main_num'] == 11))
with gr.Row():
prev_btn = gr.Button("⬅️ Previous Question")
next_btn = gr.Button("Next Question ➑️")
tts_audio = gr.Audio(autoplay=True, visible=False)
score_lines = gr.Textbox(label="Score by Question", lines=15, interactive=False)
total = gr.Textbox(label="Total Score", interactive=False)
submit_btn = gr.Button("βœ… Submit MMSE Answers")
start_over_btn = gr.Button("πŸ”„ Start Over", visible=False)
# --- Event Handler Functions specific to this tab ---
def process_evaluation_MMSE(answers, image_upload):
score_lines_out, total_out = MMSE.evaluate_MMSE(answers, image_upload)
return score_lines_out, total_out, gr.update(visible=False), gr.update(visible=True), total_out
# Wire up event listeners
audio_input.change(utils.transcribe, inputs=audio_input, outputs=answer_text)
question_button.click(MMSE.speak_question, inputs=question_index, outputs=tts_audio)
outputs_list = [question_button, answer_text, question_index, progress_text,
instruction_display, jump_nav, image_upload, audio_input, answers]
next_btn.click(lambda *args: utils.save_and_navigate("next", *args, module=MMSE),
inputs=[question_index, answer_text, answers], outputs=outputs_list)
prev_btn.click(lambda *args: utils.save_and_navigate("prev", *args, module=MMSE),
inputs=[question_index, answer_text, answers], outputs=outputs_list)
jump_nav.change(lambda *args: utils.jump_to_question(*args, module=MMSE),
inputs=[jump_nav, question_index, answer_text, answers], outputs=outputs_list)
submit_btn.click(
utils.save_final_answer, inputs=[question_index, answer_text, answers], outputs=answers
).then(
fn=process_evaluation_MMSE, inputs=[answers, image_upload], outputs=[score_lines, total, submit_btn, start_over_btn, mmse_score_state]
)
start_over_btn.click(lambda: utils.reset_app(MMSE), outputs=[
question_index, answers, score_lines, total, question_button, progress_text,
instruction_display, answer_text, jump_nav, audio_input, image_upload,
start_over_btn, submit_btn, tts_audio, mmse_score_state
])
return mmse_tab
# --- CDRM UI and Logic (Placeholder) ---
def build_cdrm_tab(cdrm_score_state):
"""Builds the fully functional UI components for the CDR Memory tab."""
with gr.Blocks() as cdrm_tab:
gr.Markdown("## CDR Memory Assessment")
# State and UI components, mirroring the MMSE tab
question_index = gr.State(0)
answers = gr.State([""] * CDRM.TOTAL_QUESTIONS)
jump_nav = gr.Dropdown(choices=CDRM.QUESTION_CHOICES, value=CDRM.QUESTION_CHOICES[0], label="Jump to Question")
initial_q = CDRM.STRUCTURED_QUESTIONS[0]
progress_text = gr.Markdown(f"## {initial_q['main_cat']} - Q{initial_q['main_num']}{initial_q['sub_letter']} ({1} of {CDRM.TOTAL_QUESTIONS})")
instruction_display = gr.Markdown(initial_q["instruction"])
question_button = gr.Button(f"Say πŸ”Š {initial_q['question']}", variant="secondary")
with gr.Group():
answer_text = gr.Textbox(label="Your Answer (type or record below)")
audio_input = gr.Audio(sources=["microphone"], label="🎀 Record Your Answer Here")
# This is now dynamic; it will only show if a drawing question is added to CDRM.py
image_upload = gr.Image(type="filepath", label="Upload Drawing", visible=("draw a copy" in initial_q["question"]))
with gr.Row():
prev_btn = gr.Button("⬅️ Previous Question")
next_btn = gr.Button("Next Question ➑️")
tts_audio = gr.Audio(autoplay=True, visible=False)
score_lines = gr.Textbox(label="Score by Question", lines=15, interactive=False)
total = gr.Textbox(label="Total Score", interactive=False)
submit_btn = gr.Button("βœ… Submit CDRM Answers")
start_over_btn = gr.Button("πŸ”„ Start Over", visible=False)
# --- Event Handler Functions specific to this tab ---
def process_evaluation_CDRM(answers):
# This now passes the answers to the evaluation function
score_lines_out, total_out = CDRM.evaluate_CDRM(answers)
return score_lines_out, total_out, gr.update(visible=False), gr.update(visible=True), total_out
# Wire up event listeners, referencing the CDRM module
audio_input.change(utils.transcribe, inputs=audio_input, outputs=answer_text)
question_button.click(CDRM.speak_question, inputs=question_index, outputs=tts_audio)
outputs_list = [question_button, answer_text, question_index, progress_text,
instruction_display, jump_nav, image_upload, audio_input, answers]
# Use the generic utils functions, passing 'module=CDRM'
next_btn.click(lambda *args: utils.save_and_navigate("next", *args, module=CDRM),
inputs=[question_index, answer_text, answers], outputs=outputs_list)
prev_btn.click(lambda *args: utils.save_and_navigate("prev", *args, module=CDRM),
inputs=[question_index, answer_text, answers], outputs=outputs_list)
jump_nav.change(lambda *args: utils.jump_to_question(*args, module=CDRM),
inputs=[jump_nav, question_index, answer_text, answers], outputs=outputs_list)
submit_btn.click(
utils.save_final_answer, inputs=[question_index, answer_text, answers], outputs=answers
).then(
fn=process_evaluation_CDRM, inputs=[answers], outputs=[score_lines, total, submit_btn, start_over_btn, cdrm_score_state]
)
# The reset function also takes the module as an argument
start_over_btn.click(lambda: utils.reset_app(CDRM), outputs=[
question_index, answers, score_lines, total, question_button, progress_text,
instruction_display, answer_text, jump_nav, audio_input, image_upload,
start_over_btn, submit_btn, tts_audio, cdrm_score_state
])
return cdrm_tab
# --- Joint Outcome UI ---
def build_joint_outcome_tab(mmse_score_state, cdrm_score_state):
"""Builds the UI for the Joint Outcome analysis tab."""
with gr.Blocks() as joint_tab:
gr.Markdown("## Joint Outcome Analysis")
gr.Markdown("This tab will use the results from the MMSE and CDR Memory tabs to provide a combined analysis.")
with gr.Row():
mmse_result = gr.Textbox(label="MMSE Final Score", interactive=False)
cdrm_result = gr.Textbox(label="CDR Memory Final Score", interactive=False)
analyze_btn = gr.Button("Analyze Joint Outcome")
outcome_display = gr.Textbox(label="Combined Analysis Result", interactive=False)
def analyze_outcomes(mmse_score, cdrm_score):
# Placeholder logic for joint analysis
if not mmse_score and not cdrm_score:
return "Please complete both assessments first."
# Example:
# mmse_val = int(mmse_score.split('/')[0].strip())
# cdrm_val = int(cdrm_score.split('/')[0].strip())
# some_logic...
return f"Analysis based on MMSE score: '{mmse_score}' and CDRM score: '{cdrm_score}'.\n\n(Full analysis logic to be implemented)"
analyze_btn.click(analyze_outcomes, inputs=[mmse_score_state, cdrm_score_state], outputs=outcome_display)
# Link state changes to the textboxes for display
mmse_score_state.change(lambda x: x, inputs=mmse_score_state, outputs=mmse_result)
cdrm_score_state.change(lambda x: x, inputs=cdrm_score_state, outputs=cdrm_result)
return joint_tab
# --- Main Application Build ---
def build_ui():
"""Builds the main Gradio interface with tabs."""
with gr.Blocks(theme=gr.themes.Soft(), title="Cognitive Assessment") as demo:
gr.Markdown("# Cognitive Assessment")
# State objects to share results between tabs
mmse_score_state = gr.State("")
cdrm_score_state = gr.State("")
with gr.Tabs():
with gr.TabItem("Joint Outcome"):
build_joint_outcome_tab(mmse_score_state, cdrm_score_state)
with gr.TabItem("MMSE"):
build_mmse_tab(mmse_score_state)
with gr.TabItem("CDR Memory"):
build_cdrm_tab(cdrm_score_state)
return demo
if __name__ == "__main__":
# Perform one-time setup for all modules
MMSE.pregenerate_audio()
CDRM.pregenerate_audio()
app = build_ui()
app.launch()