diff --git a/PanTS-Demo/src/helpers/constants.ts b/PanTS-Demo/src/helpers/constants.ts index dd27dc6..86c43bf 100644 --- a/PanTS-Demo/src/helpers/constants.ts +++ b/PanTS-Demo/src/helpers/constants.ts @@ -79,6 +79,9 @@ export const segmentation_category_colors: { [key: number]: Color } = { 30: [100, 149, 237, 254], // Renal vein left (cornflower blue) 31: [70, 130, 180, 254], // Renal vein right (steel blue) 32: [192, 192, 192, 254], // CBD stent (silver-gray) + 33: [255, 140, 0, 254], // Liver lesion (dark orange) + 34: [255, 215, 0, 254], // Kidney lesion (gold) + 35: [220, 20, 60, 254], // Colon lesion (crimson) }; // Rotating palette of colours to hand out to new classes. @@ -128,6 +131,9 @@ export const segmentation_categories: SegmentationCategories[] = [ "renal_vein_left", "renal_vein_right", "cbd_stent", + "liver_lesion", + "kidney_lesion", + "colon_lesion", ]; export const OrganSystemsArray: Systems[] = [ @@ -168,7 +174,7 @@ export const OrganSystems: OrganSystemsType = { "renal_vein_right", ], "Endocrine System": ["adrenal_gland_left", "adrenal_gland_right"], - "Urinary System": [{ Kidneys: ["kidney_left", "kidney_right"] }, "bladder"], + "Urinary System": [{ Kidneys: ["kidney_left", "kidney_right", "kidney_lesion"] }, "bladder"], // bladder "Skeletal System": ["femur_left", "femur_right"], @@ -184,10 +190,12 @@ export const OrganSystems: OrganSystemsType = { ], }, "colon", + "colon_lesion", "duodenum", "intestine", "stomach", "liver", + "liver_lesion", "common_bile_duct", "gall_bladder", "cbd_stent", diff --git a/PanTS-Demo/src/routes/UploadPage.css b/PanTS-Demo/src/routes/UploadPage.css index dd8b375..3ebdcec 100644 --- a/PanTS-Demo/src/routes/UploadPage.css +++ b/PanTS-Demo/src/routes/UploadPage.css @@ -1157,3 +1157,23 @@ background: rgba(0, 0, 0, 0.05); border-color: rgba(0, 0, 0, 0.2); } + +/* LesionSegmenter lesion-target sub-selector (appears under Model when + LesionSegmenter is chosen). Reuses .model-dropdown-btn for the select. */ +.lesion-target-select { + display: flex; + align-items: center; + gap: 8px; + margin-top: 8px; +} +.lesion-target-label { + font-size: 11px; + font-weight: 600; + color: rgba(0, 0, 0, 0.6); + text-transform: uppercase; + letter-spacing: 0.04em; +} +.lesion-target-select select.model-dropdown-btn { + flex: 1; + cursor: pointer; +} diff --git a/PanTS-Demo/src/routes/UploadPage.tsx b/PanTS-Demo/src/routes/UploadPage.tsx index 83ee9e5..85ffec5 100644 --- a/PanTS-Demo/src/routes/UploadPage.tsx +++ b/PanTS-Demo/src/routes/UploadPage.tsx @@ -165,6 +165,12 @@ const UploadPage: React.FC = () => { | "" >("None"); const [modelDropOpen, setModelDropOpen] = useState(false); + // LesionSegmenter computes liver/pancreatic/kidney/colon lesions in one pass; + // this selects which lesion to feature. Only pancreatic is GT-validated; the + // other three are surfaced as experimental. + const [lesionTarget, setLesionTarget] = useState< + "pancreatic" | "liver" | "kidney" | "colon" + >("pancreatic"); const modelDropRef = useRef(null); const [preDropOpen, setPreDropOpen] = useState(false); const preDropRef = useRef(null); @@ -571,6 +577,9 @@ const UploadPage: React.FC = () => { inferFd.append("session_id", sid); inferFd.append("model_name", model); inferFd.append("uploaded_filename", uploadedName); + if (model === "LesionSegmenter") { + inferFd.append("lesion_target", lesionTarget); + } const res = await fetch(`${API_BASE}/api/run-epai-inference`, { method: "POST", body: inferFd, @@ -1413,6 +1422,31 @@ const UploadPage: React.FC = () => { )} + {selectedModel === "LesionSegmenter" && ( +
+ + +
+ )}
diff --git a/PanTS-Demo/src/types.tsx b/PanTS-Demo/src/types.tsx index a8f3c14..9e3f3ea 100644 --- a/PanTS-Demo/src/types.tsx +++ b/PanTS-Demo/src/types.tsx @@ -122,7 +122,10 @@ export type SegmentationCategories = | "intestine" | "renal_vein_left" | "renal_vein_right" - | "cbd_stent"; + | "cbd_stent" + | "liver_lesion" + | "kidney_lesion" + | "colon_lesion"; export type OrganMeshInfo = { id: number; diff --git a/flask-server/services/auto_segmentor.py b/flask-server/services/auto_segmentor.py index 7848b46..9d9120f 100644 --- a/flask-server/services/auto_segmentor.py +++ b/flask-server/services/auto_segmentor.py @@ -206,6 +206,8 @@ def run_auto_segmentation(input_path, session_dir, model, session_id=None, on_st "superior_mesenteric_artery": 27, "veins": 28, # extended labels for full ePAI output "intestine": 29, "renal_vein_left": 30, "renal_vein_right": 31, "cbd_stent": 32, + # LesionSegmenter extra lesion classes (pancreatic_lesion already at 22) + "liver_lesion": 33, "kidney_lesion": 34, "colon_lesion": 35, } # ePAI model label → viewer label (all 25 classes from dataset.json) @@ -295,9 +297,12 @@ def run_auto_segmentation(input_path, session_dir, model, session_id=None, on_st # NOT mapped (no viewer category exists yet, left as background rather than # guessing at a slot and risking a mislabeled structure): esophagus, rectum, # vertebrae_* (10 classes), trachea, heart, hip_left, hip_right, sacrum, -# uterus, liver_lesion, kidney_lesion, colon_lesion. pancreatic_lesion is the -# one this model exists to add and maps onto the same viewer slot ePAI and -# Atlas-Net already use for their own PDAC/cyst/PNET subtypes. +# uterus. pancreatic_lesion maps onto the same viewer slot ePAI and Atlas-Net +# use for their PDAC/cyst/PNET subtypes. liver_lesion/kidney_lesion/colon_lesion +# get their own viewer slots (33/34/35) -- this single model already computes all +# four lesions in one forward pass, so surfacing the other three is free at +# runtime. NOTE: only pancreatic_lesion has ground-truth validation on PanTS; +# the other three are surfaced but flagged experimental in the UI. _LESIONSEG_TO_VIEWER = { 1: _VIEWER_LABELS["aorta"], 2: _VIEWER_LABELS["gall_bladder"], @@ -319,7 +324,10 @@ def run_auto_segmentation(input_path, session_dir, model, session_id=None, on_st 19: _VIEWER_LABELS["prostate"], 21: _VIEWER_LABELS["lung_left"], 22: _VIEWER_LABELS["lung_right"], + 39: _VIEWER_LABELS["liver_lesion"], 40: _VIEWER_LABELS["pancreatic_lesion"], + 41: _VIEWER_LABELS["kidney_lesion"], + 42: _VIEWER_LABELS["colon_lesion"], }