Data Flow

Data Flow

Label semantics, the ordered transform chain that turns a raw CT volume into a training sample, the batch contract exposed to the model, and the prediction artifacts that leave the pipeline.

Vesuvius Segmentation — Data and Tensor Flow A data-flow diagram generated by Archify. 01 / Volume data 02 / Preparation 03 / Sample + augment 04 / Batch contract 05 / Prediction CT volume · TIF / NPY · 01 / Volume data CT volume TIF / NPY Labels · 0 / 1 / 2 · 01 / Volume data Labels 0 / 1 / 2 Convert · TIFF to NPY · 02 / Preparation Convert TIFF to NPY Train / val split · test_size 0.006 · 02 / Preparation Train / val split test_size 0.006 Patch sampler · Z32 Y320 X320 · 03 / Sample + augment Patch sampler Z32 Y320 X320 Z-preserving augs · flip / rot90 · 03 / Sample + augment Z-preserving augs flip / rot90 Batch contract · 7 keys · 04 / Batch contract Batch contract 7 keys Probability volume · binary head · 05 / Prediction Probability volume binary head Distance volume · SDF head · 05 / Prediction Distance volume SDF head read volume CT input read masks annotation converted arrays on disk case lists split manifest patches train only image + SDF tensors forward binary logits forward SDF regression Legend data store data flow
From raw CT volume to scored prediction. The custom pipeline (left) and the nnU-Net pipeline (right) take different preprocessing routes but converge on the same probability-volume evaluation surface.

1. Label semantics and the ignore region

Every design decision downstream is a consequence of the label scheme. Three classes are used, and they do not carry equal weight in training:

ValueName in codeHandling
0Background Contributes to the loss as a negative, but only where it is a valid label.
1Foreground (surface) The positive target. Becomes the binary mask and the basis of the distance field.
2Unlabelled / ignore Removed from both the loss and the metric through a validity mask. Also used as the fill value when padding, so padded regions are never mistaken for real background.

The ignore class is the reason a validity mask exists at all. Annotations cover only part of each volume, so treating unlabelled voxels as background would teach the model that valid surface is background — a much more damaging error than the opposite. Every sample therefore carries an explicit mask saying which voxels are trustworthy.

2. Raw data to training arrays

A carbonised, still-sealed ancient scroll shown beside the same X-ray CT volume virtually unrolled into a flat surface
The sealed scroll and its virtual unrolling from CT data. Source: AIhub.

Scans arrive as 3D TIFF volumes. Because TIFF decoding is slow relative to training throughput, they are converted once to memory-mappable NumPy arrays and the training pipeline reads the converted form:

raw scan volume (.tif)  →  one-time TIFF-to-NumPy conversion  →  <data_dir>/train_images/*.npy
                                                                        <data_dir>/train_labels/*.npy

Conversion is a one-time preparation step, not part of the training loop. The conversion utility is a local working script and is not published with the repository; everything downstream depends only on the resulting <data_dir>/{train_images,train_labels} layout. The case identifier is the filename stem, and that same identifier threads through the dataset, the inference output filenames and the scoring report, which is what makes per-case debugging possible.

3. The transform chain

A training sample is not “a volume”: it is the output of an ordered chain of MONAI transforms. Order is load-bearing, and two properties of the chain matter more than any individual transform.

First, geometry is decided before content. Padding, cropping and augmentation all happen while the label is still a plain three-class map; only once a patch is final does the code derive the binary mask, the validity mask and the distance fields. This keeps the expensive derived arrays proportional to patch size rather than volume size.

Second, every geometry transform is paired with an appropriate fill value. Image padding fills with 0 (empty space), while label padding fills with 2 (ignore) so that synthetic padding can never be scored as a confident negative.

#TransformPurpose
1Load volume and labelReads the converted arrays for one case.
2Ensure channel firstVolumes are stored without a channel dimension; adds one.
3Scale intensity rangeMaps raw intensities to 0–1.
4Spatial padding (image, fill 0) Guarantees the patch is extractable from volumes smaller than the patch size.
5Spatial padding (label, fill 2)
6Build crop label Constructs the map that drives foreground-weighted sampling.
7Random patch crop, positive-weighted Draws a patch centred on foreground. This is essential: uniform sampling would produce almost exclusively empty patches at this foreground density.
8Augmentation set See the note below — applied to geometry and appearance, with the scroll axis respected.
9Extract foregroundReduces the three-class map to a binary foreground mask.
10Copy foregroundRetains an untouched copy of the binary mask for the explicit positive-class target.
11Extract valid maskBuilds the mask that excludes ignore voxels from the loss.
12Signed distance transform Produces the distance field the auxiliary head regresses: negative inside the sheet, positive outside, normalised to a bounded range.
13Unsigned distance transform Produces a one-sided distance field capped at a maximum distance, giving the main head a graded signal near the surface where the binary label alone is nearly all zeros.

Validation uses a shorter chain The validation pipeline stops at intensity scaling and derives the same label tensors, but skips padding, cropping and augmentation. Validation must see the case as it will be seen at inference time, so any transform that changes geometry is confined to training.

4. The batch contract

This is the interface between data and model, and the place most readers need to slow down. Each sample exposes several keys, and each key has exactly one consumer:

KeyContentsConsumed by
pixel_values The normalised and augmented image patch. The network input.
label_fg_bin Binary surface mask. The binary classification head’s target.
label_fg Signed distance field derived from the binary mask. The auxiliary regression head’s target.
label_valid Validity mask excluding ignore voxels. Loss masking, so ignore voxels never contribute.
distance_unsigned Capped one-sided distance field. Distance-based loss components.
idx, id Position in the split and case identifier. Traceability: which case and which patch a metric belongs to.

Two design choices are worth calling out. The dataset returns two distance representations rather than one: the signed field gives the auxiliary head a well-posed regression target that changes smoothly through the sheet boundary, while the capped unsigned field gives the distance-based loss terms a bounded local signal. And the dataset returns both a binary mask and its distance transform, so the two heads can be supervised from one patch without recomputation.

5. Training / validation split

Cases are partitioned once with a fixed random seed and a small held-out fraction, so a run is reproducible and every experiment sees the same split. The held-out cases are also the ones the sliding-window validation pass scores, which keeps validation cost proportional to a fraction of the dataset rather than to all of it.

6. Prediction artifacts

Inference inverts the chain. A trained checkpoint consumes image patches and writes, per case, two arrays in half precision to keep volumes manageable:

<output_dir>/
├── probabilities/<case_id>.npy     foreground probability volume
└── distance_preds/<case_id>.npy    predicted distance field

Everything after this point — thresholding, morphology, topological repair and scoring — operates on those files rather than on the network. That separation is deliberate: it makes post-processing a pure function of stored predictions, so strategies can be swept and compared without re-running inference. The Evaluation & Metrics page describes that stage, and Pipelines covers inference in context.