mlqlf-space / app.py
pangyuteng
added aserts for file existence checking
f5ac43f
import os
import sys
import json
import uuid
import shutil
import tempfile
import pydicom
import datetime
from datetime import timezone
import pandas as pd
import SimpleITK as sitk
from huggingface_hub import snapshot_download
import gradio as gr
from gradio_pdf import PDF
HF_ACCESS_TOKEN = os.environ.get("HF_ACCESS_TOKEN")
USERNAME = os.environ.get("USERNAME")
PASSWORD = os.environ.get("PASSWORD")
dlqlf_model_folder = snapshot_download(repo_id="cvib/dlqlf-model",repo_type='model',token=HF_ACCESS_TOKEN)
# we are pulling report_utils from cvib/dlqlf-model
sys.path.append(os.path.join(dlqlf_model_folder,"report"))
from report_utils import NiftiVisualizer
mlqlf_repo_folder = snapshot_download(repo_id="cvib/mlqlf-model",repo_type='model',token=HF_ACCESS_TOKEN)
sys.path.append(os.path.join(mlqlf_repo_folder,"lungseg","src"))
sys.path.append(os.path.join(mlqlf_repo_folder,"mlqlf","src"))
from lungqia import compute_lungqia_wrapper
from foobar import transform_lungqia_to_mlqlf
def imread(file_list):
reader = sitk.ImageSeriesReader()
reader.SetFileNames(file_list)
img_obj = reader.Execute()
return img_obj
def main_func(input_file_list):
with tempfile.TemporaryDirectory() as tempdir:
print('start time:',datetime.datetime.now(timezone.utc).strftime('%Y-%m-%d-%H-%M-%S-%Z'))
image_file = os.path.join(tempdir,f"image.nii.gz")
first_file = input_file_list[0].name
file_list = []
if first_file.endswith(".dcm"):
for x in input_file_list:
file_path = x.name
ds = pydicom.dcmread(file_path,stop_before_pixels=True)
item = dict(
file_path=file_path,
instance_number=int(ds.InstanceNumber)
)
file_list.append(item)
file_list = sorted(file_list,key=lambda x:x['instance_number'])
file_list = [x['file_path'] for x in file_list]
img_obj = imread(file_list)
else:
raise ValueError("only accept .dcm files!")
sitk.WriteImage(img_obj,image_file)
seri_file = os.path.join(tempdir,'image.seri')
with open(seri_file,'w') as f:
for x in file_list:
f.write(f"{x}\n")
work_dir = os.path.join(tempdir,f"work_dir")
compute_lungqia_wrapper(seri_file,tempdir,lungseg_enable=True,work_dir=work_dir)
novsl_nifti_file = os.path.join(work_dir,"novsl.nii.gz")
wlung_nifti_file = os.path.join(work_dir,"wlung.nii.gz")
lungqia_csv = os.path.join(tempdir,"lungqia_results.csv")
assert(os.path.exists(novsl_nifti_file))
assert(os.path.exists(wlung_nifti_file))
assert(os.path.exists(lungqia_csv))
transform_lungqia_to_mlqlf(lungqia_csv,novsl_nifti_file,wlung_nifti_file,tempdir)
mlqlf_csv_file = os.path.join(tempdir,"mlqlf.csv")
mlqlf_nifti_file = os.path.join(tempdir,"mlqlf.nii.gz")
assert(os.path.exists(mlqlf_csv_file))
assert(os.path.exists(mlqlf_nifti_file))
my_uid = uuid.uuid4().hex
output_pdf_file = os.path.join('/tmp',f'{my_uid}.pdf')
output_csv_file = os.path.join('/tmp',f'{my_uid}.csv')
inst = NiftiVisualizer("NA",image_file,mlqlf_nifti_file,mlqlf_csv_file,tempdir)
tmp_pdf_file = inst.gen_pdf()
assert(os.path.exists(tmp_pdf_file))
output_df = pd.read_csv(mlqlf_csv_file)
shutil.copy(tmp_pdf_file,output_pdf_file)
shutil.copy(mlqlf_csv_file,output_csv_file)
print('uid:',os.path.basename(output_csv_file))
print('end time:',datetime.datetime.now(timezone.utc).strftime('%Y-%m-%d-%H-%M-%S-%Z'))
return output_pdf_file, output_df, output_pdf_file, output_csv_file
with gr.Blocks() as demo:
with gr.Column():
gr.Markdown(
"""
# demo - MLQLF (aka LDTA)
+ on the left panel, drag dicom files that belong to the same series to below box.
+ wait for files to be uploaded and click the `process` button at the bottom of the left panel.
+ wait for process to be completed to download the pdf/json on the right panel.
""")
with gr.Row():
with gr.Column():
in_file = gr.File(label="upload dicom files here",file_count='multiple')
btn = gr.Button("process")
with gr.Column():
pdf = PDF(label="Upload a PDF", interactive=True)
gr_df = gr.Dataframe()
download_button_pdf = gr.DownloadButton("Download report pdf", visible=True)
download_button_csv = gr.DownloadButton("Download report csv", visible=True)
btn.click(fn=main_func,
inputs=[in_file],
outputs=[pdf,gr_df,download_button_pdf,download_button_csv],
)
if __name__ == "__main__":
demo.queue().launch(
server_name="0.0.0.0",
debug=True,
show_api=True,
share=False,
auth=(USERNAME,PASSWORD),
)
"""
docker run -it -u $(id -u):$(id -g) -p 7860:7860 \
-v $PWD:/opt/demo -w /opt/demo --env-file=.env \
mlqlf-gradio bash
python app.py
"""