PanTS_Website / services /auto_segmentor.py
jen900704's picture
Upload 40 files
e9406c7 verified
import os
import uuid
import subprocess
import re
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
def get_least_used_gpu(default_gpu=None):
if default_gpu is None:
try:
available_gpus_str = os.getenv("AVAILABLE_GPUS", "")
available_gpus = [int(x) for x in available_gpus_str.split(",") if x.strip().isdigit()]
if not available_gpus:
raise ValueError("No available GPUs specified.")
result = subprocess.check_output(
["nvidia-smi", "--query-gpu=memory.used", "--format=csv,noheader,nounits"],
universal_newlines=True
)
mem_usages = [int(x) for x in result.strip().split("\n")]
least_used_gpu = min(available_gpus, key=lambda i: mem_usages[i])
return str(least_used_gpu)
except Exception as e:
print("⚠️ Failed to get GPU info, defaulting to 0:", e)
return "0"
else:
return str(default_gpu)
def run_auto_segmentation(input_path, session_dir, model):
"""
Run auto segmentation model using Apptainer inside the given session directory.
"""
subfolder_name = "ct"
input_case_dir = os.path.join(session_dir, "inputs")
outputs_root = os.path.join(session_dir, "outputs")
input_case_ct_dir = os.path.join(input_case_dir, subfolder_name)
os.makedirs(input_case_ct_dir, exist_ok=True)
os.makedirs(outputs_root, exist_ok=True)
input_filename = os.path.basename(input_path)
container_input_path = os.path.join(input_case_ct_dir, input_filename)
os.system(f"cp {input_path} {container_input_path}")
conda_activate_cmd = ""
conda_path = os.getenv("CONDA_ACTIVATE_PATH", "/opt/anaconda3/etc/profile.d/conda.sh")
epai_env_name = os.getenv("CONDA_ENV_EPAI", "epai")
suprem_sandbox_path = os.getenv("SUPREM_SANDBOX_PATH", "")
epai_script_path = os.getenv("EPAI_SCRIPT_PATH", "")
if model == 'SuPreM':
container_path = suprem_sandbox_path
print(input_case_dir, outputs_root)
apptainer_cmd = [
"apptainer", "run", "--nv",
"-B", f"{input_case_dir}:/workspace/inputs",
"-B", f"{outputs_root}:/workspace/outputs",
container_path
]
elif model == 'ePAI':
conda_activate_cmd = f"source {conda_path} && conda activate {epai_env_name} &&"
apptainer_cmd = ["bash", epai_script_path, session_dir]
else:
print(f"[ERROR] Unknown model: {model}")
return None
selected_gpu = get_least_used_gpu()
apptainer_cmd = ["CUDA_VISIBLE_DEVICES=" + selected_gpu] + apptainer_cmd
print(apptainer_cmd)
try:
print(f"[INFO] Running {model} auto segmentation for file: {input_filename}")
full_cmd = f"{conda_activate_cmd} {' '.join(apptainer_cmd)}"
subprocess.run(full_cmd, shell=True, executable="/bin/bash", check=True)
except subprocess.CalledProcessError as e:
print(f"[ERROR] {model} inference failed:", e)
return None
if model == 'SuPreM':
output_path = os.path.join(outputs_root, subfolder_name, "segmentations")
if not os.path.exists(output_path):
print("[ERROR] Output mask not found at:", output_path)
return None
elif model == 'ePAI':
output_path = os.path.join(outputs_root, subfolder_name, "combined_labels.nii.gz")
if not os.path.exists(output_path):
print("[ERROR] Output mask not found at:", output_path)
return None
output_path = os.path.join(outputs_root, subfolder_name)
return output_path