import streamlit as st import numpy as np import matplotlib.pyplot as plt from io import BytesIO from dosemetrics_app.utils import read_byte_data from dosemetrics_app.utils import get_example_datasets, load_example_files def request_dose_and_masks(instruction_text): """Helper function to request dose and mask file uploads or example selection""" st.markdown(instruction_text) st.markdown(f"Check instructions on the sidebar for more information.") # Add option to use example data data_source = st.radio( "Data source:", ["Upload your own files", "Use example data"], horizontal=True ) dose_file = None mask_files = None if data_source == "Upload your own files": dose_file = st.file_uploader( "Upload a dose distribution volume (in .nii.gz)", type=["gz"] ) mask_files = st.file_uploader( "Upload mask volumes (in .nii.gz)", accept_multiple_files=True, type=["gz"] ) else: # Load example data example_datasets = get_example_datasets() if example_datasets: # Get list of dataset names with test_subject first dataset_names = list(example_datasets.keys()) default_index = ( dataset_names.index("test_subject") if "test_subject" in dataset_names else 0 ) selected_dataset = st.selectbox( "Select example dataset:", options=dataset_names, index=default_index ) if selected_dataset: dataset_path = example_datasets[selected_dataset] with st.spinner("Loading example data..."): dose_path, mask_paths = load_example_files(dataset_path) if dose_path: # Read files and create BytesIO objects for compatibility with open(dose_path, "rb") as f: dose_bytes = BytesIO(f.read()) dose_bytes.name = dose_path.name dose_file = dose_bytes mask_files = [] for mask_path in mask_paths: with open(mask_path, "rb") as f: mask_bytes = BytesIO(f.read()) mask_bytes.name = mask_path.name mask_files.append(mask_bytes) st.success( f"Loaded {len(mask_files)} structures from {selected_dataset}" ) else: st.warning("Example data not available. Please upload your own files.") data_source = "Upload your own files" return dose_file, mask_files def panel(): """Main panel function for Visualize Dose tab""" st.sidebar.success("Select an option above.") instruction_text = f"## Step 1: Upload dose distribution volume and mask files" dose_file, mask_files = request_dose_and_masks(instruction_text) files_uploaded = (dose_file is not None) and ( mask_files is not None and len(mask_files) > 0 ) if files_uploaded: st.divider() st.markdown(f"## Step 2: Visualize Dose") dose_volume, structure_masks = read_byte_data(dose_file, mask_files) plt.figure(figsize=(6, 6), dpi=80) fig, ax = plt.subplots() slice_num = st.slider("Choose an axial slice number:", 1, 128, 64) plt.imshow(np.rot90(dose_volume[:, :, slice_num], 3), cmap="hot") plt.tick_params( axis="x", # changes apply to the x-axis which="both", # both major and minor ticks are affected bottom=False, # ticks along the bottom edge are off top=False, # ticks along the top edge are off labelbottom=False, ) plt.tick_params( axis="y", # changes apply to the x-axis which="both", # both major and minor ticks are affected left=False, # ticks along the bottom edge are off right=False, # ticks labelleft=False, ) plt.title("Dose Volume") st.pyplot(fig)