Parallax Pathology · Russell Parrish, analysis carried out with Claude (Anthropic) · 5–6 November 2026 · lab book for round 4 of the external CRC benchmark · published November 2026
Published as written at the time, apart from this header. File and folder names refer to the project record, available on request. Benchmark note · Claim ledger
Before round 4 the sealed tiles had four logged looks (0 to 3). Same rule: develop on NCT (all) and the 1,800 development tiles only; one logged look at a frozen version (../EXTERNAL_CRC_ROUND2_20261105/LOOK_LOG.md).
scripts/r4_axes.py: 70 fields, fixed and label-free, each a named quantity of the tile. The existing v1/v2 families separate the stains but rescale each one within the tile, which removes absolute stain amounts; r4 keeps them.
rgb2hed, no rescaling) and CIELab, measured on tissue with nuclei (Otsu on haematoxylin, dilated 2 px) removed: percentiles, haematoxylin-to-eosin ratio, hue, chroma, eosin smoothness at two scales.The fields are built to be rotation-invariant. On 6 test tiles rotated by 90°, one field moved by more than 5% (nuclear waviness, through the pixel grid). Speed about 0.08 s per tile. Measured with round-1 violet protection on all 100,000 NCT tiles (from the external drive, checkpointed), the 1,800 development tiles and, after the freeze, the 5,380 sealed tiles: no failures; the gate flagged 363, 103 and 75 tiles, as in every round.
Area under the curve of each field, NCT and development tiles (outputs/02_transfer.csv); 60 of 70 fields point the same way in both collections with |AUC − 0.5| > 0.05 for at least one of the two pairs.
| Stroma vs muscle | NCT | Development | Normal vs tumour | NCT | Development | |
|---|---|---|---|---|---|---|
| H/E ratio, non-nuclear tissue | 0.714 | 0.863 | Gabor energy, 16 px | 0.801 | 0.923 | |
| Haematoxylin, 10th percentile | 0.602 | 0.761 | Lightness (L*), median | 0.828 | 0.908 | |
| Chromatin texture | 0.406 | 0.246 | Haematoxylin, 90th percentile | 0.242 | 0.103 | |
| Red-green (a*), median | 0.285 | 0.254 | DAB channel, median | 0.179 | 0.106 | |
| DAB channel, median | 0.416 | 0.263 | Chroma, median | 0.154 | 0.119 |
AUC above 0.5 means higher in stroma (left) or normal (right). The best earlier stroma/muscle field reached about 0.79 on development tiles.
Median haematoxylin over median eosin in the non-nuclear tissue. Smooth-muscle cytoplasm takes eosin strongly; collagen and ground substance hold relatively more haematoxylin.
| Median ratio | Muscle | Stroma | Debris | Tumour | Lymphocytes | Normal | Adipose |
|---|---|---|---|---|---|---|---|
| NCT | 0.39 | 0.51 | 0.45 | 0.63 | 0.68 | 0.80 | 5.4 |
| Development | 0.34 | 0.53 | 0.54 | 0.61 | 0.57 | 0.59 | 1.08 |
Limits: it helps the stroma/muscle boundary, not the whole picture (debris, tumour and lymphocytes sit nearby); it is unstable on tiles with little tissue (adipose); it depends on a working stain separation; and it reads orange-rendered tissue as nearly unstained (Entry 9).
| Development tiles | Gradient boosting (500) | Logistic | Average of both | Stroma (avg) |
|---|---|---|---|---|
| Round-3 fields (148) | 89.1% | 86.4% | 91.0% | 0.74 |
| + r4, all (218) | 90.6% | 86.0% | 91.5% | 0.68 |
| + r4, transfer-screened (208) | 90.0% | 85.3% | 90.3% | 0.66 |
| Shift-screened, max class shift ≤ 0.5 SD (59) | 89.2% | 82.0% | 88.9% | 0.61 |
| Shift-screened, ≤ 0.75 SD (110) | 90.7% | 85.9% | 91.4% | 0.61 |
| Shift-screened, ≤ 1.0 SD (152) | 90.6% | 83.9% | 90.8% | 0.64 |
Shift screen: for each field and class, (development median − NCT median) / NCT standard deviation; fields kept if the largest absolute shift over the nine classes is within the bound. Every version gains muscle and loses stroma. Development stroma is denser and more aligned than NCT stroma (Gabor anisotropy is about 0.5 SD higher in both development stroma and development muscle, which moves stroma towards muscle), and development adipose has far less tissue per tile (tissue fraction shifted −4.3 SD), which destabilises its colour fields.
The six views make different mistakes. Averaging the class probabilities of all twelve readouts (six views × two readouts) gives 92.4% on development tiles. About 240 subsets of eight readouts from four of the views were also scored (best 92.6%); the rule "every view, both readouts" was taken instead of the best subset. Three views are chosen with development labels (transfer and shift screens), so a split-half check was run: screens chosen on one stratified half, ensemble scored on the other, then swapped (scripts/04_split_half.py): 92.1%.
FROZEN_ROUND4.md and hashes. Primary: the twelve-readout average, all fitted once on the 100,000 NCT tiles; screens recomputed at look time from NCT and the 1,800 development tiles, identical to development. Secondary, same look: round-3 fields + r4 all, gradient boosting and logistic only (no screening on development labels).
| 5,380 sealed tiles | Accuracy (95% tile-level) | Balanced | Stroma | Muscle | Normal |
|---|---|---|---|---|---|
| Look 2: + v1/v2 extensions, gradient boosting | 91.5% (90.7–92.2) | 89.4% | 0.706 | 0.852 | 0.819 |
| Look 3: direction-free, boosting + logistic | 91.6% (90.9–92.3) | 89.9% | 0.719 | 0.814 | 0.860 |
| Look 4: + r4, six views averaged | 93.8% (93.1–94.4) | 91.0% | 0.643 | 0.890 | 0.915 |
| Look 4: + r4, single view (secondary) | 91.6% (90.9–92.3) | 89.5% | 0.611 | 0.885 | 0.884 |
Primary recall by class: adipose 0.931, background 1.000, debris 0.914, lymphocytes 0.963, mucus 0.980, muscle 0.890, normal 0.915, stroma 0.643, tumour 0.956. 5,044 of 5,380 correct (336 errors). Tile by tile against look 3: 234 newly right, 120 newly wrong (paired sign test p ≈ 1 × 10⁻⁹).
| Sealed confusion | Look 3 | Look 4 |
|---|---|---|
| Muscle → stroma (of 392) | 70 | 3 |
| Stroma → muscle (of 221) | 48 | 50 |
| Stroma → tumour / debris | 5 / 0 | 15 / 8 |
| Normal → tumour (of 541) | 48 | 39 |
| Muscle → mucus (of 392) | 0 | 38 |
| Adipose → muscle (of 1,138) | 40 | 52 |
On development tiles the twelve-readout average calls 17 muscle tiles mucus (round-3 fields alone: 1). They are rendered orange-tan. The fixed stain vectors read orange as almost unstained: H/E ratio 0.06 against 0.37 for correctly called muscle, eosin median 0.011 against 0.034 (mucus 0.010). Label-free, mean red minus mean blue above 30 flags 28 development muscle tiles, 4 debris and 2 stroma, and no other class. The sealed muscle-to-mucus error was not opened; on development tiles it has this cause.
Ratio of haematoxylin to eosin in non-nuclear tissue: fixed Ruifrok–Johnston deconvolution (scikit-image rgb2hed, no per-tile rescaling); nuclei masked by Otsu on haematoxylin within tissue, dilated 2 px; median H ÷ median E over the remaining tissue. Stroma vs muscle AUC 0.714 on NCT-CRC-HE-100K and 0.863 on CRC-VAL development tiles, same direction. In look 4 it is one of 70 new fields inside a six-view average that reached 93.8% on sealed tiles; its separate contribution on sealed tiles has not been isolated. Conditions: a minimum amount of non-nuclear tissue; a working stain separation (the earlier degenerate Macenko normaliser, with stain vectors 0.17° apart, would flatten it); and a rendering check, since orange-rendered tissue reads as nearly unstained. Code: EXTERNAL_CRC_ROUND4_20261105/scripts/r4_axes.py.