Skip to content

Commit

Permalink
Merge branch 'ag-dev' into ge-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderGetka-cbica authored Dec 18, 2024
2 parents 98bcd1b + 74cc2b6 commit 3a6ec4f
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 7 deletions.
8 changes: 7 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
.git
test
test_data
output_folder
output_folder/**
!output_folder/NiChart_sMRI_Demo1
!output_folder/NiChart_sMRI_Demo2
**/*.nii.gz
build
**/build
src/NiChart_Website

# Ignore hidden files and directories
.*

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,4 @@ test/test_output

## make sure no data go to the repo
##*.nii.gz

7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,17 @@ RUN grep -v -E '^(torch)' /tmp/requirements.txt > /tmp/requirements2.txt
USER root
RUN apt-get update && apt-get install -y python3-tk git
USER $MAMBA_USER
RUN pip install --verbose -r /tmp/requirements2.txt && pip uninstall -y torch && pip install --verbose torch==2.3.1 --index-url https://download.pytorch.org/whl/cu${CUDA_VERSION}
RUN pip install --verbose -r /tmp/requirements2.txt
RUN mkdir ~/dummyinput && mkdir ~/dummyoutput
RUN git clone https://github.com/CBICA/PredCRD.git && cd PredCRD && pip install -e .
RUN git clone https://github.com/CBICA/DLWMLS.git && cd DLWMLS && pip install -e . && DLWMLS -i ~/dummyinput -o ~/dummyoutput
RUN pip uninstall -y torch && pip install --verbose torch==2.3.1 --index-url https://download.pytorch.org/whl/cu${CUDA_VERSION}
## Cache DLMUSE and DLICV models with an empty job so no download is needed later
RUN DLMUSE -i ~/dummyinput -o ~/dummyoutput && DLICV -i ~/dummyinput -o ~/dummyoutput
USER root
COPY . /app/
RUN useradd -s /bin/bash streamlit && mkdir /app/output_folder && \
chmod a+w /app/output_folder && chmod a-rw / && chmod a-w /app && touch /app/src/viewer/pipeline.log && \
RUN useradd -s /bin/bash streamlit && \
chmod -R a+rw /app/output_folder && chmod a-rw / && chmod a-w /app && touch /app/src/viewer/pipeline.log && \
chmod a+rw /app/src/viewer/pipeline.log
USER streamlit
WORKDIR /app/src/viewer/
Expand Down
5 changes: 5 additions & 0 deletions cloud-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lambda_urls": {
"update_stats": "https://gpzw2o0kxd.execute-api.us-east-1.amazonaws.com/default/cbica-nichart-updatestats"
}
}
10 changes: 7 additions & 3 deletions src/viewer/pages/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import utils.utils_session as utilss
import utils.utils_st as utilst
from streamlit_extras.stylable_container import stylable_container
import webbrowser
from streamlitextras.webutils import stxs_javascript

# Page config should be called for each page
utilss.config_page()
Expand Down Expand Up @@ -123,12 +123,16 @@ def set_pipeline() -> None:
if st.button(
'📝 NiChart User Experience',
):
webbrowser.open_new_tab('https://forms.office.com/r/mM1kx1XsgS')
## This code only works locally, not on a container or server.
#webbrowser.open_new_tab('https://forms.office.com/r/mM1kx1XsgS')
stxs_javascript('''window.open('https://forms.office.com/r/mM1kx1XsgS', '_blank').focus()''')

if st.button(
'📝 Shaping the Future of NiChart',
):
webbrowser.open_new_tab('https://forms.office.com/r/acwgn2WCc4')
## This code only works locally, not on a container or server.
#webbrowser.open_new_tab('https://forms.office.com/r/acwgn2WCc4')
stxs_javascript('''window.open('https://forms.office.com/r/acwgn2WCc4', '_blank').focus()''')

### Bg color on link_button was not supported in styllable container
#st.link_button(
Expand Down
4 changes: 4 additions & 0 deletions src/viewer/pages/prep_sMRI_dicomtonifti.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import utils.utils_nifti as utilni
import utils.utils_session as utilss
import utils.utils_st as utilst
import utils.utils_cloud as utilcloud
from stqdm import stqdm

# Page config should be called for each page
Expand Down Expand Up @@ -242,6 +243,9 @@ def panel_extract() -> None:
)
if num_nifti == 0:
st.warning(':material/thumb_down: The extraction process did not produce any Nifti images!')
else:
if st.session_state.has_cloud_session:
utilcloud.update_stats_db(st.session_state.cloud_user_id, "NIFTIfromDICOM", num_nifti)

df_files = utilio.get_file_names(
st.session_state.paths[st.session_state.sel_mod], ".nii.gz"
Expand Down
4 changes: 4 additions & 0 deletions src/viewer/pages/process_sMRI_DLMUSE.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import utils.utils_rois as utilroi
import utils.utils_session as utilss
import utils.utils_st as utilst
import utils.utils_cloud as utilcloud
from stqdm import stqdm

# Page config should be called for each page
Expand Down Expand Up @@ -174,6 +175,9 @@ def panel_dlmuse() -> None:

with st.spinner("Wait for it..."):
fcount = utilio.get_file_count(st.session_state.paths["T1"])
if st.session_state.has_cloud_session:
utilcloud.update_stats_db(st.session_state.cloud_user_id, "DLMUSE", fcount)

progress_bar = stqdm(total=9, desc="Current step", position=0)
progress_bar.set_description("Starting...")

Expand Down
5 changes: 5 additions & 0 deletions src/viewer/pages/process_sMRI_DLWMLS.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import utils.utils_nifti as utilni
import utils.utils_session as utilss
import utils.utils_st as utilst
import utils.utils_cloud as utilcloud
from stqdm import stqdm

# Page config should be called for each page
Expand Down Expand Up @@ -164,6 +165,10 @@ def panel_dlwmls() -> None:
os.makedirs(st.session_state.paths["dlwmls"])

with st.spinner("Wait for it..."):
fcount = utilio.get_file_count(st.session_state.paths["FL"])
if st.session_state.has_cloud_session:
utilcloud.update_stats_db(st.session_state.cloud_user_id, "DLWMLS", fcount)

dlwmls_cmd = f"DLWMLS -i {st.session_state.paths['FL']} -o {st.session_state.paths['dlwmls']} -d {device}"
st.info(f"Running: {dlwmls_cmd}", icon=":material/manufacturing:")

Expand Down
4 changes: 4 additions & 0 deletions src/viewer/pages/workflow_sMRI_MLScores.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import utils.utils_menu as utilmenu
import utils.utils_session as utilss
import utils.utils_st as utilst
import utils.utils_cloud as utilcloud

run_dir = os.path.join(st.session_state.paths["root"], "src", "workflows", "w_sMRI")
sys.path.append(run_dir)
Expand Down Expand Up @@ -284,6 +285,9 @@ def panel_run() -> None:

with st.spinner("Wait for it..."):
st.info("Running: mlscores_workflow ", icon=":material/manufacturing:")
fcount = df_tmp.shape[0]
if st.session_state.has_cloud_session:
utilcloud.update_stats_db(st.session_state.cloud_user_id, "MLScores", fcount)

try:
if flag_harmonize:
Expand Down
47 changes: 47 additions & 0 deletions src/viewer/utils/utils_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import requests
import json
import os

def load_cloud_config(config_file: str):
"""
Load Lambda URLs from a local JSON file.
"""
try:
with open(config_file, "r") as f:
config = json.load(f)
return config
except FileNotFoundError:
raise FileNotFoundError(f"Configuration file '{config_file}' not found.")
except json.JSONDecodeError:
raise ValueError(f"Error parsing the configuration file '{config_file}'.")

def update_stats_db(user_id, job_type, count):
current_dir = os.path.dirname(os.path.abspath(__file__))

# Traverse up to the top-level directory (assuming 'config.json' is in the repo root)
repo_root = os.path.abspath(os.path.join(current_dir, "..", "..", ".." ))
print(f"repo root: {repo_root}")

# Construct the full path to the config file
config_file = os.path.join(repo_root, "cloud-config.json")
cloud_config = load_cloud_config(config_file)

lambda_urls = cloud_config.get("lambda_urls", None)
if lambda_urls is None:
print("Lambda URL not provided in cloud config!")

update_stats_url = lambda_urls["update_stats"]

payload = {
"user_id": user_id,
"job_type": job_type,
"count": count
}
headers = {"Content-Type": "application/json"}

try:
response = requests.post(update_stats_url, json=payload, headers=headers)
#response.raise_for_status()
print("Success:", response.json())
except requests.exceptions.RequestException as e:
print("Error:", e)
14 changes: 14 additions & 0 deletions src/viewer/utils/utils_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import utils.utils_rois as utilroi
import utils.utils_io as utilio
from PIL import Image
import shutil

from streamlit.web.server.websocket_headers import _get_websocket_headers
import jwt
Expand Down Expand Up @@ -212,6 +213,19 @@ def init_session_state() -> None:

if not os.path.exists(st.session_state.paths["dir_out"]):
os.makedirs(st.session_state.paths["dir_out"])

# Copy demo folders into user folders as needed
if st.session_state.has_cloud_session:
## Copy demo dirs to user folder (TODO: make this less hardcoded)
demo_dir_paths = [os.path.join(st.session_state.paths["root"], "output_folder", "NiChart_sMRI_Demo1" ),
os.path.join(st.session_state.paths["root"], "output_folder", "NiChart_sMRI_Demo2" )
]
for demo in demo_dir_paths:
demo_name = os.path.basename(demo)
destination_path = os.path.join(st.session_state.paths["dir_out"], demo_name)
if os.path.exists(destination_path):
shutil.rmtree(destination_path)
shutil.copytree(demo, destination_path, dirs_exist_ok=True)

############
# FIXME : set init folder to test folder outside repo
Expand Down

0 comments on commit 3a6ec4f

Please sign in to comment.