Branchseed · Toralis Labs
25 CT angiograms
Find every artery that leaves the supplied aorta and return each as a separate daughter instance. Cut the aortic wall open along its length and flatten it, and that search becomes a reading: every daughter is a mark at a distance and a clock position. This page is the submission, laid out against the five things it is scored on.
The table below is what the pipeline returns, not a grade. The counts come with no per-case adjustment anywhere, and the rejection ledger underneath is where candidates are actually spent: far more are refused than accepted, each for a stated reason.
| Case | Daughters | Segment | Per 100 mm | Lumen | Opacification | Mean ∅ | Rejected | Runtime |
|---|
Click any column to sort, any row to open that case. Opacification is the lower quartile of the aortic lumen in Hounsfield units. Iodinated arterial blood sits far above 150 HU; unopacified blood sits near 40.
On subjects 18 and 24 the aorta was never opacified, so a daughter lumen cannot be told from muscle by brightness and there is nothing to find. An earlier build returned 34 and 16 daughters on those two; both were noise. The test is the lower quartile of the aortic lumen against an absolute floor of 150 HU, which reads 194 HU or higher on the other twenty-three cases and 50 and 18 on these two. The groups do not overlap. Above the floor nothing changes; below it the bar rises to something only a genuinely bright tubular structure can clear. This costs recall on two cases and protects precision on all of them.
One thumbnail per daughter, cut in the plane containing both that branch's own direction and the aortic axis, then projected through a five millimetre slab. The aorta runs vertically in each frame and the branch runs to the right. Every detection is here, in case order, not a selection of the convincing ones. Click any thumbnail to open it.
The same flattening applied to every case and hung on one scale, so a column is a patient and a row across is a depth. Segment lengths differ enormously, which is most of why the counts differ. Click a strip to open that case.
Scored on physical distance between the predicted and reference ostium centre. The map below is where those centres come from: vertical is distance down the supplied segment, horizontal is position around the wall, and darkness is how far contrast-filled tissue continues outward. Each centre is the point furthest from the rim of the patch where that tissue meets the wall, reported in the millimetre frame SimpleITK returns, not voxel indices.
Calibre
Flattened wall
Daughters found
Scored on three things: whether the seed lies on the matched daughter, whether the direction follows its proximal path, and whether the radius matches the daughter lumen. All three come from the same walk outward from the opening, shell by shell, stopping at the first bifurcation or ten millimetres. Pick a daughter and the viewer jumps to the slice its opening sits on, with the seed and direction drawn where they land.
The seed usually sits on a different slice from the opening, so it fades separately. Both markers dim as you scrub away from the level they belong to.
Taken five millimetres along the traced path, not five millimetres along a straight line, so it stays inside a vessel that curves as it leaves.
A line fit over the proximal path rather than a two-point difference, so a single noisy voxel at the opening cannot swing it, across a window of three times the vessel's own radius.
Measured on a half-maximum contour in the plane cut across the vessel at the seed. That keeps it sub-voxel on 1.5 mm scans instead of stepping in half-voxel jumps.
In the axial view a daughter is a bright dot present for a slice or two. Cut along the body instead, projected through a six millimetre slab, and the same vessel is a spur running away from the aorta over a centimetre. A dot can be noise; a spur of that length cannot.
The pipeline was built from first principles and then checked against prior work on the same problem, which turned up two things it had wrong and one that did not survive contact with this data.
Tahoces takes the contact point as the voxel furthest from the edge of the contact area. An opening cut obliquely through the wall is often crescent shaped, and the centroid of a crescent sits on its rim or off it entirely: it did so on 26.8% of patches here, usually landing inside the aortic lumen. The rim-distance maximum is inside the patch every time, and moves the reported point by a median of 1.5 mm.
Riffaud fits the direction a branch leaves at over three times its own radius. A lumbar artery a millimetre across and a renal four times that were sharing a flat 6 mm window here. The radius is now measured on a provisional fit and the direction fitted again at the right scale.
Danilov cleans vessel masks by walking distance layers inward from the farthest one, dropping voxels with no neighbour further out. Ported directly it anchors on each label's farthest point, which on this data is frequently a leak rather than the vessel, so it kept the leak and deleted the branch. It cost subject 2 both its coeliac and mesenteric arteries before being reverted.
The walk halts at the first bifurcation. A vessel arising from another daughter is not a direct aortic daughter, so the trace has no business following it.
The brief allows sixty seconds a case on four cores and eight gigabytes, with no GPU and no network. This runs single-threaded on one core, so there are three cores of headroom left unused.
Everything runs inside a box drawn around the supplied mask with a 31 mm margin, so cost tracks the length of aorta given rather than the size of the file. A 490 mm segment costs more than a 60 mm one from the same scanner.
Distance transforms and the outward label propagation dominate. Both are ordinary array work, which is why peak memory stays close to the volume itself.
One setup command, one run command, no per-case edits anywhere. The loader sniffs each file rather than trusting its extension, because part of the development set ships gzip-compressed under a plain .nii name; a reader that trusts the name fails on ten of the twenty-five.
pip install -r requirements.txt python run.py --image image.nii.gz --aorta-mask aorta_mask.nii.gz --output prediction.json
Every point is checked against SimpleITK.TransformIndexToPhysicalPoint and agrees to six decimal places. Getting this backwards puts every point in the wrong place while still looking plausible, so it is verified rather than assumed.
A case that throws writes a valid file with an empty daughters list rather than taking the batch down with it. No prediction is ever a guess about a vessel that is not visible.
Subject 24 has direction cosines that are not orthonormal, so SimpleITK refuses to open it at all. The loader here reads it. Worth knowing if the reference pipeline uses SimpleITK to read.
No randomness anywhere, no learned weights, no network. The same input gives the same output on any machine with the listed dependencies.
Two things the flattened representation gives away for free once every case is in the same frame. Neither is graded; both are why the representation is worth having.