Source code for autods_pet.imaging.segmentation

"""Thin wrapper around TotalSegmentator CLI."""

from __future__ import annotations

import logging
import subprocess
from pathlib import Path

log = logging.getLogger(__name__)

#: Default filename for the multilabel segmentation output.
TOTSEG_FILENAME = "TotSeg_multilabel.nii.gz"


[docs] def run_totalsegmentator( ct_path: Path, output_dir: Path, task: str = "total", fast: bool = False, output_filename: str | None = None, ) -> Path: """Run TotalSegmentator on a CT image. Uses the ``--ml`` flag to produce a single multilabel NIfTI file named :data:`TOTSEG_FILENAME` inside *output_dir*. .. note:: Paths are passed as subprocess arguments (list form, no shell). This mitigates OS command injection (CWE-78), but path traversal (CWE-22) is not validated. If this function is ever exposed via a network service, add explicit path validation. Parameters ---------- ct_path : Path Path to the input CT NIfTI file. output_dir : Path Directory where the segmentation output will be written. task : str TotalSegmentator task name (default ``"total"``). fast : bool If True, use the ``--fast`` flag for lower resolution but faster inference. output_filename : str or None Custom filename for the output segmentation file. When ``None`` (default), uses :data:`TOTSEG_FILENAME`. Returns ------- Path Path to the output segmentation file. """ ct_path = Path(ct_path) output_dir = Path(output_dir) output_dir.mkdir(parents=True, exist_ok=True) # With --ml, -o is a FILE path (not directory). output_file = output_dir / (output_filename or TOTSEG_FILENAME) cmd = [ "TotalSegmentator", "-i", str(ct_path), "-o", str(output_file), "--task", task, "--ml", ] if fast: cmd.append("--fast") result = subprocess.run(cmd, check=True, capture_output=True, text=True) if result.stdout: log.debug("TotalSegmentator stdout: %s", result.stdout) if result.stderr: log.debug("TotalSegmentator stderr: %s", result.stderr) if output_file.exists(): return output_file raise FileNotFoundError( f"TotalSegmentator output not found: expected {output_file}" )