"""Detect CT vs MRI directly from the uploaded volume's voxel intensities,
rather than relying on the user's query text mentioning the modality.
Why this exists: a user asking "segment the liver" while uploading a CT
volume very often won't say the word "CT" at all -- the modality is implicit
in the file, not necessarily in the sentence. Falling back to the LLM's
parsed `modality` field (which can legitimately be "not specified") for
task routing would silently misroute CT volumes to the MRI model. Image
intensity is a much more reliable signal: CT values are calibrated
Hounsfield units where air is always ~-1000 HU, while MRI intensities are
arbitrary per-scan units that are essentially never that negative.
"""
import nibabel as nib
import numpy as np
# Air in CT is ~ -1000 HU; real MRI images essentially never go this negative.
CT_MIN_HU_THRESHOLD = -500
def detect_modality(path):
"""Returns "CT" or "MR" based on the 1st percentile voxel intensity."""
img = nib.load(str(path))
data = img.get_fdata()
p1 = float(np.percentile(data, 1))
return "CT" if p1 < CT_MIN_HU_THRESHOLD else "MR"