Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion PanTS-Demo/src/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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[] = [
Expand Down Expand Up @@ -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"],

Expand All @@ -184,10 +190,12 @@ export const OrganSystems: OrganSystemsType = {
],
},
"colon",
"colon_lesion",
"duodenum",
"intestine",
"stomach",
"liver",
"liver_lesion",
"common_bile_duct",
"gall_bladder",
"cbd_stent",
Expand Down
20 changes: 20 additions & 0 deletions PanTS-Demo/src/routes/UploadPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
34 changes: 34 additions & 0 deletions PanTS-Demo/src/routes/UploadPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLDivElement>(null);
const [preDropOpen, setPreDropOpen] = useState(false);
const preDropRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -1413,6 +1422,31 @@ const UploadPage: React.FC = () => {
</div>
)}
</div>
{selectedModel === "LesionSegmenter" && (
<div className="lesion-target-select">
<label
htmlFor="lesion-target"
className="lesion-target-label"
>
Lesion
</label>
<select
id="lesion-target"
className="model-dropdown-btn"
value={lesionTarget}
onChange={(e) =>
setLesionTarget(
e.target.value as typeof lesionTarget
)
}
>
<option value="pancreatic">Pancreatic lesion</option>
<option value="liver">Liver lesion (experimental)</option>
<option value="kidney">Kidney lesion (experimental)</option>
<option value="colon">Colon lesion (experimental)</option>
</select>
</div>
)}
</div>

<div className="pipeline-arrow">→</div>
Expand Down
5 changes: 4 additions & 1 deletion PanTS-Demo/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 11 additions & 3 deletions flask-server/services/auto_segmentor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"],
Expand All @@ -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"],
}


Expand Down
Loading