Repository navigation
feat(NII): split a label at a cumulative-volume fraction or at its center of mass - #146
Conversation
…bel_at_center_of_mass Two reusable label-splitting kernels lifted out of paraside's split_ethmoid, which hard-coded the ethmoid label ids (7/8/15/16) and offsets (+100/+200) around otherwise generic logic. split_label_at_cumulative_volume_fraction walks slices inwards from the axis-most end of a mask, summing voxels until a given fraction of the total volume is covered, and adds an offset to the labels of that slab. Note this is a volume fraction, not an extent fraction, so a structure that is thin at one end is not cut in the middle of its bounding box. split_label_at_center_of_mass cuts at the rounded center of mass along an axis and offsets the labels on the axis side of the plane. Changes from the source implementation: - the axis is an anatomical direction resolved against `orientation`, so the reorient round-trip the original did (and the reorient back at the end) is gone, and either method can also take a raw array axis as an int - the center-of-mass rounding happens in the anatomical frame, so the split is identical whichever orientation the image is stored in; rounding in the array frame shifted it by a slice when the center of mass landed on a voxel center - the offset is applied via a mask instead of `arr[slab] += offset` followed by `arr[arr == offset] = 0`, which silently breaks for any label equal to the offset, and the dtype is promoted when the offset would overflow it - fraction 0 now yields an empty slab; the original had no such case and its loop left `cutoff_slice` as None when the threshold was never reached, which then crashed on an undefined variable - labels not present in the mask are a no-op instead of a KeyError A test composes the two into the original ethmoid pipeline; the result is voxel-identical to split_ethmoid. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFZf44LHBB6N5jaf6YFzhx
Benchmark comparisonSpeed (wall time per call)baseline Showing the 5 most-changed measurements per case; the rest are collapsed. Rows with a baseline below 3 ms are tagged
|
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
nii_save |
11.33 ±0.17 | 11.97 ±0.51 | +5.6% | 0.050 |
poi_calc_centroids_nocrop |
4.19 ±0.30 | 4.00 ±0.23 | -4.6% | 0.576 |
nii_load_img |
10.51 ±0.13 | 10.96 ±0.13 | +4.3% | 0.000 |
nii_fill_holes |
4.42 ±0.10 | 4.35 ±0.06 | -1.6% | 0.303 |
poi_calc_poi_from_subreg_vert |
12.36 ±0.09 | 12.50 ±0.10 | +1.2% | 0.068 |
… 31 more measurements
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
nii_erode_msk |
6.00 ±0.05 | 6.06 ±0.07 | +1.0% | 0.061 |
nii_rescale |
39.71 ±0.18 | 39.94 ±0.22 | +0.6% | 0.233 |
nii_filter_connected_components |
4.12 ±0.04 | 4.14 ±0.08 | +0.4% | 0.394 |
nii_dilate_msk |
121.45 ±0.30 | 121.10 ±0.35 | -0.3% | 0.216 |
nii_rescale_seg |
3.18 ±0.06 | 3.19 ±0.03 | +0.3% | 0.339 |
nii_resample_from_to |
41.95 ±0.63 | 41.92 ±0.36 | -0.1% | 0.459 |
metric_voxels |
250463.00 ±0.00 | 250463.00 ±0.00 | +0.0% | — |
metric_labels |
3.00 ±0.00 | 3.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
14.51 ±0.00 | 14.51 ±0.00 | +0.0% | — |
nii_get_array |
0.03 ±0.00 | 0.06 ±0.01 | +90.9% (noise) | 0.000 |
poi_rescale |
0.16 ±0.02 | 0.22 ±0.01 | +41.4% (noise) | 0.002 |
poi_reorient |
0.30 ±0.03 | 0.39 ±0.04 | +29.2% (noise) | 0.011 |
poi_to_global |
0.14 ±0.02 | 0.18 ±0.03 | +27.2% (noise) | 0.097 |
nii_extract_label |
0.41 ±0.03 | 0.33 ±0.06 | -18.9% (noise) | 0.085 |
poi_local_to_global_arr |
0.26 ±0.01 | 0.31 ±0.02 | +18.2% (noise) | 0.010 |
nii_load_seg |
2.51 ±0.09 | 2.90 ±0.06 | +15.4% (noise) | 0.001 |
poi_resample_from_to |
0.56 ±0.03 | 0.63 ±0.06 | +13.0% (noise) | 0.061 |
nii_set_dtype |
0.47 ±0.15 | 0.52 ±0.02 | +11.1% (noise) | 0.830 |
nii_apply_crop |
0.60 ±0.05 | 0.66 ±0.05 | +10.5% (noise) | 0.333 |
poi_map_labels |
0.13 ±0.01 | 0.14 ±0.02 | +7.9% (noise) | 0.157 |
nii_unique |
0.67 ±0.02 | 0.62 ±0.06 | -6.8% (noise) | 0.727 |
nii_reorient |
0.80 ±0.11 | 0.85 ±0.04 | +6.5% (noise) | 0.281 |
poi_calc_centroids |
2.27 ±0.02 | 2.42 ±0.07 | +6.3% (noise) | 0.013 |
nii_pad_to |
0.64 ±0.08 | 0.61 ±0.07 | -5.1% (noise) | 0.870 |
nii_volumes |
1.85 ±0.04 | 1.95 ±0.04 | +5.1% (noise) | 0.002 |
nii_center_of_masses |
1.74 ±0.05 | 1.80 ±0.01 | +3.3% (noise) | 0.020 |
nii_get_connected_components |
2.09 ±0.05 | 2.15 ±0.10 | +3.1% (noise) | 0.241 |
nii_compute_crop |
0.33 ±0.03 | 0.32 ±0.01 | -2.6% (noise) | 0.343 |
nii_map_labels |
0.95 ±0.03 | 0.93 ±0.04 | -1.6% (noise) | 0.198 |
poi_save |
0.39 ±0.02 | 0.40 ±0.02 | +1.2% (noise) | 0.352 |
poi_load |
0.89 ±0.02 | 0.88 ±0.02 | -1.2% (noise) | 0.512 |
ct_2d — shape (73, 47, 1)
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
nii_resample_from_to |
7.55 ±0.25 | 7.35 ±0.10 | -2.6% | 0.130 |
nii_rescale |
5.37 ±0.24 | 5.24 ±0.13 | -2.5% | 0.468 |
nii_dilate_msk |
14.30 ±0.03 | 14.38 ±0.07 | +0.6% | 0.038 |
metric_voxels |
3431.00 ±0.00 | 3431.00 ±0.00 | +0.0% | — |
metric_labels |
3.00 ±0.00 | 3.00 ±0.00 | +0.0% | — |
… 30 more measurements
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
metric_foreground_pct |
37.60 ±0.00 | 37.60 ±0.00 | +0.0% | — |
nii_center_of_masses |
0.21 ±0.01 | 0.23 ±0.02 | +12.7% (noise) | 0.047 |
nii_volumes |
0.27 ±0.02 | 0.30 ±0.01 | +11.1% (noise) | 0.018 |
nii_rescale_seg |
0.86 ±0.18 | 0.77 ±0.02 | -9.6% (noise) | 0.218 |
nii_map_labels |
0.47 ±0.02 | 0.51 ±0.01 | +8.8% (noise) | 0.004 |
poi_calc_centroids |
0.90 ±0.05 | 0.97 ±0.03 | +7.9% (noise) | 0.014 |
poi_calc_centroids_nocrop |
1.09 ±0.03 | 1.18 ±0.03 | +7.4% (noise) | 0.004 |
nii_extract_label |
0.40 ±0.04 | 0.42 ±0.03 | +7.0% (noise) | 0.199 |
nii_fill_holes |
0.80 ±0.03 | 0.86 ±0.01 | +6.7% (noise) | 0.052 |
nii_apply_crop |
0.68 ±0.03 | 0.72 ±0.02 | +6.1% (noise) | 0.026 |
poi_save |
0.47 ±0.02 | 0.50 ±0.04 | +5.3% (noise) | 0.067 |
poi_resample_from_to |
0.76 ±0.04 | 0.72 ±0.03 | -5.3% (noise) | 0.048 |
poi_to_global |
0.21 ±0.01 | 0.22 ±0.01 | +5.1% (noise) | 0.027 |
nii_erode_msk |
0.95 ±0.03 | 1.00 ±0.02 | +5.1% (noise) | 0.023 |
nii_pad_to |
0.55 ±0.02 | 0.57 ±0.03 | +5.0% (noise) | 0.084 |
nii_get_connected_components |
0.62 ±0.04 | 0.65 ±0.02 | +4.9% (noise) | 0.079 |
nii_get_array |
0.02 ±0.00 | 0.02 ±0.00 | -4.3% (noise) | 0.192 |
poi_map_labels |
0.18 ±0.01 | 0.19 ±0.01 | +4.0% (noise) | 0.101 |
nii_unique |
0.11 ±0.00 | 0.12 ±0.00 | +4.0% (noise) | 0.011 |
nii_set_dtype |
0.41 ±0.02 | 0.39 ±0.01 | -3.4% (noise) | 0.517 |
poi_local_to_global_arr |
0.32 ±0.02 | 0.33 ±0.01 | +3.1% (noise) | 0.454 |
nii_compute_crop |
0.15 ±0.01 | 0.15 ±0.00 | -2.7% (noise) | 0.113 |
nii_filter_connected_components |
0.81 ±0.10 | 0.83 ±0.02 | +2.5% (noise) | 0.916 |
nii_load_seg |
1.62 ±0.08 | 1.65 ±0.03 | +1.9% (noise) | 0.716 |
nii_save |
1.36 ±0.12 | 1.34 ±0.08 | -1.4% (noise) | 0.924 |
nii_load_img |
1.44 ±0.04 | 1.46 ±0.07 | +1.4% (noise) | 0.405 |
nii_reorient |
0.82 ±0.03 | 0.83 ±0.02 | +0.8% (noise) | 0.931 |
poi_reorient |
0.44 ±0.03 | 0.43 ±0.01 | -0.7% (noise) | 0.496 |
poi_rescale |
0.24 ±0.02 | 0.24 ±0.00 | -0.1% (noise) | 0.757 |
poi_load |
1.02 ±0.03 | 1.02 ±0.03 | -0.0% (noise) | 0.691 |
mri_3d — shape (68, 52, 67)
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
nii_rescale |
37.98 ±0.28 | 37.07 ±0.22 | -2.4% | 0.002 |
nii_rescale_seg |
3.12 ±0.05 | 3.06 ±0.03 | -2.0% | 0.048 |
nii_resample_from_to |
39.84 ±0.19 | 39.32 ±0.25 | -1.3% | 0.003 |
nii_load_img |
8.62 ±0.10 | 8.52 ±0.06 | -1.2% | 0.036 |
nii_save |
9.27 ±0.07 | 9.17 ±0.12 | -1.2% | 0.574 |
… 31 more measurements
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_calc_centroids_nocrop |
8.41 ±0.31 | 8.50 ±0.09 | +1.1% | 0.304 |
nii_filter_connected_components |
4.61 ±0.05 | 4.65 ±0.06 | +0.8% | 0.226 |
poi_calc_poi_from_subreg_vert |
11.71 ±0.17 | 11.63 ±0.12 | -0.7% | 0.875 |
nii_dilate_msk |
158.33 ±0.49 | 157.53 ±1.34 | -0.5% | 0.583 |
nii_erode_msk |
7.70 ±0.15 | 7.73 ±0.10 | +0.3% | 0.471 |
nii_fill_holes |
5.34 ±0.07 | 5.34 ±0.10 | +0.0% | 0.759 |
metric_voxels |
236912.00 ±0.00 | 236912.00 ±0.00 | +0.0% | — |
metric_labels |
8.00 ±0.00 | 8.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
18.21 ±0.00 | 18.21 ±0.00 | +0.0% | — |
nii_apply_crop |
0.76 ±0.03 | 0.70 ±0.04 | -7.7% (noise) | 0.009 |
nii_get_array |
0.05 ±0.01 | 0.05 ±0.00 | -6.6% (noise) | 0.305 |
poi_save |
0.52 ±0.02 | 0.55 ±0.03 | +5.6% (noise) | 0.080 |
poi_reorient |
0.48 ±0.02 | 0.46 ±0.03 | -4.7% (noise) | 0.145 |
poi_map_labels |
0.22 ±0.01 | 0.23 ±0.02 | +3.8% (noise) | 0.258 |
poi_local_to_global_arr |
0.33 ±0.01 | 0.32 ±0.01 | -3.6% (noise) | 0.116 |
nii_unique |
0.66 ±0.02 | 0.64 ±0.01 | -3.0% (noise) | 0.086 |
poi_calc_centroids |
2.73 ±0.02 | 2.81 ±0.05 | +2.6% (noise) | 0.025 |
poi_rescale |
0.27 ±0.00 | 0.27 ±0.01 | -2.5% (noise) | 0.069 |
nii_compute_crop |
0.33 ±0.02 | 0.32 ±0.01 | -2.2% (noise) | 0.394 |
nii_get_connected_components |
2.16 ±0.02 | 2.21 ±0.04 | +2.0% (noise) | 0.123 |
poi_resample_from_to |
0.76 ±0.02 | 0.75 ±0.03 | -1.7% (noise) | 0.423 |
nii_reorient |
0.85 ±0.04 | 0.86 ±0.02 | +1.3% (noise) | 0.681 |
poi_load |
2.19 ±0.07 | 2.21 ±0.06 | +0.9% (noise) | 0.878 |
nii_center_of_masses |
1.96 ±0.03 | 1.97 ±0.01 | +0.6% (noise) | 0.951 |
nii_set_dtype |
0.49 ±0.03 | 0.49 ±0.03 | -0.5% (noise) | 0.540 |
nii_map_labels |
0.97 ±0.02 | 0.97 ±0.02 | -0.4% (noise) | 0.572 |
nii_extract_label |
0.43 ±0.03 | 0.43 ±0.01 | +0.3% (noise) | 0.676 |
nii_pad_to |
0.70 ±0.04 | 0.70 ±0.02 | +0.3% (noise) | 0.733 |
poi_to_global |
0.25 ±0.01 | 0.25 ±0.01 | +0.2% (noise) | 0.364 |
nii_load_seg |
2.77 ±0.08 | 2.77 ±0.09 | -0.2% (noise) | 0.860 |
nii_volumes |
1.93 ±0.03 | 1.93 ±0.02 | -0.2% (noise) | 0.754 |
mri_2d — shape (68, 52, 1)
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
nii_rescale |
5.37 ±0.06 | 5.25 ±0.02 | -2.3% | 0.004 |
nii_resample_from_to |
7.55 ±0.12 | 7.41 ±0.10 | -1.9% | 0.170 |
nii_dilate_msk |
19.07 ±0.15 | 19.01 ±0.13 | -0.3% | 0.257 |
metric_voxels |
3536.00 ±0.00 | 3536.00 ±0.00 | +0.0% | — |
metric_labels |
7.00 ±0.00 | 7.00 ±0.00 | +0.0% | — |
… 30 more measurements
| Measurement | baseline ms (median ±½·range) | head ms (median ±½·range) | Δ % | p |
|---|---|---|---|---|
metric_foreground_pct |
50.17 ±0.00 | 50.17 ±0.00 | +0.0% | — |
nii_set_dtype |
0.41 ±0.02 | 0.36 ±0.03 | -12.5% (noise) | 0.099 |
nii_get_array |
0.02 ±0.00 | 0.02 ±0.00 | +10.5% (noise) | 0.818 |
nii_map_labels |
0.45 ±0.03 | 0.49 ±0.03 | +8.8% (noise) | 0.342 |
nii_apply_crop |
0.68 ±0.02 | 0.64 ±0.02 | -5.3% (noise) | 0.036 |
nii_reorient |
0.85 ±0.03 | 0.81 ±0.06 | -4.6% (noise) | 0.621 |
nii_pad_to |
0.54 ±0.03 | 0.52 ±0.01 | -4.5% (noise) | 0.106 |
nii_erode_msk |
1.30 ±0.04 | 1.25 ±0.04 | -4.5% (noise) | 0.389 |
nii_filter_connected_components |
0.86 ±0.02 | 0.82 ±0.03 | -4.2% (noise) | 0.195 |
poi_map_labels |
0.22 ±0.01 | 0.21 ±0.03 | -3.5% (noise) | 0.515 |
nii_compute_crop |
0.14 ±0.01 | 0.14 ±0.00 | -3.3% (noise) | 0.032 |
poi_save |
0.52 ±0.03 | 0.50 ±0.02 | -3.1% (noise) | 0.349 |
poi_calc_centroids_nocrop |
1.44 ±0.07 | 1.40 ±0.03 | -2.8% (noise) | 0.582 |
poi_load |
2.00 ±0.02 | 1.95 ±0.04 | -2.6% (noise) | 0.020 |
nii_volumes |
0.45 ±0.02 | 0.46 ±0.01 | +2.3% (noise) | 0.817 |
poi_rescale |
0.26 ±0.02 | 0.26 ±0.00 | -2.2% (noise) | 0.170 |
nii_fill_holes |
1.09 ±0.07 | 1.06 ±0.02 | -2.1% (noise) | 0.180 |
poi_local_to_global_arr |
0.33 ±0.01 | 0.32 ±0.02 | -2.0% (noise) | 0.596 |
poi_to_global |
0.24 ±0.01 | 0.25 ±0.01 | +1.8% (noise) | 0.381 |
nii_unique |
0.12 ±0.01 | 0.12 ±0.01 | +1.5% (noise) | 0.495 |
nii_rescale_seg |
0.76 ±0.04 | 0.75 ±0.03 | -1.3% (noise) | 0.743 |
poi_calc_centroids |
1.14 ±0.03 | 1.15 ±0.08 | +0.6% (noise) | 0.511 |
poi_resample_from_to |
0.77 ±0.04 | 0.77 ±0.02 | -0.5% (noise) | 0.531 |
nii_center_of_masses |
0.40 ±0.01 | 0.40 ±0.01 | +0.5% (noise) | 0.133 |
nii_load_seg |
1.60 ±0.06 | 1.60 ±0.05 | -0.4% (noise) | 0.755 |
nii_get_connected_components |
0.61 ±0.04 | 0.61 ±0.02 | -0.4% (noise) | 0.929 |
nii_extract_label |
0.41 ±0.01 | 0.41 ±0.05 | -0.3% (noise) | 0.546 |
nii_save |
1.31 ±0.04 | 1.31 ±0.05 | -0.1% (noise) | 0.578 |
nii_load_img |
1.45 ±0.05 | 1.45 ±0.05 | -0.1% (noise) | 0.528 |
poi_reorient |
0.44 ±0.03 | 0.44 ±0.02 | +0.0% (noise) | 0.684 |
Gate: a measurement fails when the baseline is ≥ 1 ms, the median grows by ≥ 50%, and Welch's t-test gives p < 0.05. metric_* rows are context only.
Memory (peak RSS growth per call)
baseline 59217fe vs head 59217fe · python 3.11.17 · 5 repeats + 1 warmup · sampler proc-status, isolation fork · measurement floor ≈ 0.90 MiB
Showing the 5 most-changed measurements per case; the rest are collapsed. Rows with a baseline below 3 MiB are tagged (noise) — runner jitter on those swamps any real change.
ct_3d — shape (73, 47, 73)
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_resample_from_to |
5.23 ±0.00 | 5.28 ±0.00 | +0.8% | — |
nii_reorient |
5.86 ±0.00 | 5.91 ±0.00 | +0.7% | — |
nii_rescale |
6.12 ±0.00 | 6.17 ±0.00 | +0.7% | — |
nii_resample_from_to |
6.25 ±0.00 | 6.29 ±0.00 | +0.7% | — |
nii_erode_msk |
5.93 ±0.00 | 5.92 ±0.00 | -0.2% | — |
… 31 more measurements
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_to_global |
3.08 ±0.00 | 3.08 ±0.00 | +0.1% | — |
nii_center_of_masses |
3.27 ±0.00 | 3.27 ±0.00 | +0.1% | — |
nii_volumes |
3.52 ±0.00 | 3.52 ±0.00 | +0.1% | — |
nii_save |
3.70 ±0.00 | 3.71 ±0.00 | +0.1% | — |
poi_reorient |
3.83 ±0.00 | 3.83 ±0.00 | +0.1% | — |
nii_set_dtype |
5.24 ±0.00 | 5.24 ±0.00 | +0.1% | — |
nii_extract_label |
5.36 ±0.00 | 5.37 ±0.00 | +0.1% | — |
nii_pad_to |
5.42 ±0.00 | 5.43 ±0.00 | +0.1% | — |
nii_map_labels |
5.49 ±0.00 | 5.49 ±0.00 | +0.1% | — |
nii_apply_crop |
5.86 ±0.00 | 5.86 ±0.00 | +0.1% | — |
poi_calc_centroids_nocrop |
5.92 ±0.00 | 5.93 ±0.00 | +0.1% | — |
nii_dilate_msk |
5.93 ±0.00 | 5.93 ±0.00 | +0.1% | — |
nii_rescale_seg |
5.94 ±0.00 | 5.94 ±0.00 | +0.1% | — |
poi_calc_centroids |
6.05 ±0.00 | 6.05 ±0.00 | +0.1% | — |
nii_fill_holes |
6.28 ±0.00 | 6.28 ±0.00 | +0.1% | — |
nii_get_connected_components |
6.61 ±0.00 | 6.62 ±0.00 | +0.1% | — |
nii_filter_connected_components |
6.86 ±0.00 | 6.87 ±0.00 | +0.1% | — |
poi_calc_poi_from_subreg_vert |
7.11 ±0.00 | 7.11 ±0.00 | -0.1% | 0.016 |
nii_load_img |
3.56 ±0.00 | 3.56 ±0.00 | +0.0% | — |
nii_load_seg |
6.00 ±0.00 | 6.00 ±0.00 | +0.0% | — |
metric_voxels |
250463.00 ±0.00 | 250463.00 ±0.00 | +0.0% | — |
metric_labels |
3.00 ±0.00 | 3.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
14.51 ±0.00 | 14.51 ±0.00 | +0.0% | — |
poi_save |
1.39 ±0.00 | 1.40 ±0.00 | +0.3% (noise) | — |
poi_load |
1.61 ±0.00 | 1.61 ±0.00 | +0.2% (noise) | — |
nii_get_array |
1.64 ±0.00 | 1.65 ±0.00 | +0.2% (noise) | — |
poi_map_labels |
1.77 ±0.00 | 1.77 ±0.00 | +0.2% (noise) | — |
poi_rescale |
2.60 ±0.00 | 2.61 ±0.00 | +0.2% (noise) | — |
nii_compute_crop |
2.89 ±0.00 | 2.90 ±0.00 | +0.1% (noise) | — |
poi_local_to_global_arr |
2.95 ±0.00 | 2.96 ±0.00 | +0.1% (noise) | — |
nii_unique |
2.96 ±0.00 | 2.96 ±0.00 | +0.1% (noise) | — |
ct_2d — shape (73, 47, 1)
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_resample_from_to |
5.17 ±0.00 | 5.21 ±0.00 | +0.8% | — |
nii_reorient |
5.80 ±0.00 | 5.84 ±0.00 | +0.7% | — |
nii_rescale |
6.06 ±0.00 | 6.11 ±0.00 | +0.7% | — |
nii_resample_from_to |
6.19 ±0.00 | 6.23 ±0.00 | +0.7% | — |
nii_erode_msk |
5.87 ±0.00 | 5.86 ±0.00 | -0.2% | — |
… 30 more measurements
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_to_global |
3.02 ±0.00 | 3.02 ±0.00 | +0.1% | — |
nii_center_of_masses |
3.21 ±0.00 | 3.21 ±0.00 | +0.1% | — |
nii_volumes |
3.46 ±0.00 | 3.46 ±0.00 | +0.1% | — |
nii_save |
3.64 ±0.00 | 3.64 ±0.00 | +0.1% | — |
poi_reorient |
3.77 ±0.00 | 3.77 ±0.00 | +0.1% | — |
nii_set_dtype |
5.18 ±0.00 | 5.18 ±0.00 | +0.1% | — |
nii_extract_label |
5.30 ±0.00 | 5.30 ±0.00 | +0.1% | — |
nii_pad_to |
5.36 ±0.00 | 5.36 ±0.00 | +0.1% | — |
nii_map_labels |
5.43 ±0.00 | 5.43 ±0.00 | +0.1% | — |
nii_apply_crop |
5.80 ±0.00 | 5.80 ±0.00 | +0.1% | — |
nii_dilate_msk |
5.86 ±0.00 | 5.87 ±0.00 | +0.1% | — |
nii_rescale_seg |
5.88 ±0.00 | 5.88 ±0.00 | +0.1% | — |
poi_calc_centroids_nocrop |
5.92 ±0.00 | 5.93 ±0.00 | +0.1% | — |
poi_calc_centroids |
5.99 ±0.00 | 5.99 ±0.00 | +0.1% | — |
nii_fill_holes |
6.21 ±0.00 | 6.22 ±0.00 | +0.1% | — |
nii_get_connected_components |
6.55 ±0.00 | 6.55 ±0.00 | +0.1% | — |
nii_filter_connected_components |
6.80 ±0.00 | 6.80 ±0.00 | +0.1% | — |
nii_load_img |
3.50 ±0.00 | 3.50 ±0.00 | +0.0% | — |
nii_load_seg |
5.94 ±0.00 | 5.94 ±0.00 | +0.0% | — |
metric_voxels |
3431.00 ±0.00 | 3431.00 ±0.00 | +0.0% | — |
metric_labels |
3.00 ±0.00 | 3.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
37.60 ±0.00 | 37.60 ±0.00 | +0.0% | — |
poi_save |
1.33 ±0.00 | 1.34 ±0.00 | +0.3% (noise) | — |
poi_load |
1.55 ±0.00 | 1.55 ±0.00 | +0.3% (noise) | — |
nii_get_array |
1.58 ±0.00 | 1.59 ±0.00 | +0.2% (noise) | — |
poi_map_labels |
1.71 ±0.00 | 1.71 ±0.00 | +0.2% (noise) | — |
poi_rescale |
2.54 ±0.00 | 2.54 ±0.00 | +0.2% (noise) | — |
nii_compute_crop |
2.83 ±0.00 | 2.84 ±0.00 | +0.1% (noise) | — |
poi_local_to_global_arr |
2.89 ±0.00 | 2.89 ±0.00 | +0.1% (noise) | — |
nii_unique |
2.89 ±0.00 | 2.90 ±0.00 | +0.1% (noise) | — |
mri_3d — shape (68, 52, 67)
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_resample_from_to |
5.17 ±0.00 | 5.21 ±0.00 | +0.8% | — |
nii_reorient |
5.80 ±0.00 | 5.84 ±0.00 | +0.7% | — |
nii_rescale |
6.06 ±0.00 | 6.11 ±0.00 | +0.7% | — |
nii_resample_from_to |
6.19 ±0.00 | 6.23 ±0.00 | +0.7% | — |
nii_erode_msk |
5.87 ±0.00 | 5.86 ±0.00 | -0.2% | — |
… 31 more measurements
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_to_global |
3.02 ±0.00 | 3.02 ±0.00 | +0.1% | — |
nii_center_of_masses |
3.21 ±0.00 | 3.21 ±0.00 | +0.1% | — |
nii_volumes |
3.46 ±0.00 | 3.46 ±0.00 | +0.1% | — |
nii_save |
3.64 ±0.00 | 3.64 ±0.00 | +0.1% | — |
poi_reorient |
3.77 ±0.00 | 3.77 ±0.00 | +0.1% | — |
nii_set_dtype |
5.24 ±0.00 | 5.24 ±0.00 | +0.1% | — |
nii_extract_label |
5.30 ±0.00 | 5.30 ±0.00 | +0.1% | — |
nii_pad_to |
5.36 ±0.00 | 5.36 ±0.00 | +0.1% | — |
nii_map_labels |
5.43 ±0.00 | 5.43 ±0.00 | +0.1% | — |
nii_apply_crop |
5.80 ±0.00 | 5.80 ±0.00 | +0.1% | — |
poi_calc_centroids_nocrop |
5.86 ±0.00 | 5.86 ±0.00 | +0.1% | — |
nii_dilate_msk |
5.86 ±0.00 | 5.87 ±0.00 | +0.1% | — |
nii_rescale_seg |
5.88 ±0.00 | 5.88 ±0.00 | +0.1% | — |
poi_calc_centroids |
5.99 ±0.00 | 5.99 ±0.00 | +0.1% | — |
nii_fill_holes |
6.21 ±0.00 | 6.22 ±0.00 | +0.1% | — |
nii_get_connected_components |
6.55 ±0.00 | 6.55 ±0.00 | +0.1% | — |
nii_filter_connected_components |
6.80 ±0.00 | 6.80 ±0.00 | +0.1% | — |
poi_calc_poi_from_subreg_vert |
7.11 ±0.00 | 7.11 ±0.00 | +0.1% | — |
nii_load_img |
3.56 ±0.00 | 3.56 ±0.00 | +0.0% | — |
nii_load_seg |
5.94 ±0.00 | 5.94 ±0.00 | +0.0% | — |
metric_voxels |
236912.00 ±0.00 | 236912.00 ±0.00 | +0.0% | — |
metric_labels |
8.00 ±0.00 | 8.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
18.21 ±0.00 | 18.21 ±0.00 | +0.0% | — |
poi_save |
1.39 ±0.00 | 1.40 ±0.00 | +0.3% (noise) | — |
poi_load |
1.55 ±0.00 | 1.55 ±0.00 | +0.3% (noise) | — |
nii_get_array |
1.58 ±0.00 | 1.59 ±0.00 | +0.2% (noise) | — |
poi_map_labels |
1.71 ±0.00 | 1.71 ±0.00 | +0.2% (noise) | — |
poi_rescale |
2.54 ±0.00 | 2.54 ±0.00 | +0.2% (noise) | — |
nii_compute_crop |
2.83 ±0.00 | 2.84 ±0.00 | +0.1% (noise) | — |
poi_local_to_global_arr |
2.89 ±0.00 | 2.89 ±0.00 | +0.1% (noise) | — |
nii_unique |
2.89 ±0.00 | 2.90 ±0.00 | +0.1% (noise) | — |
mri_2d — shape (68, 52, 1)
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_resample_from_to |
5.17 ±0.00 | 5.21 ±0.00 | +0.8% | — |
nii_reorient |
5.80 ±0.00 | 5.84 ±0.00 | +0.7% | — |
nii_rescale |
6.06 ±0.00 | 6.11 ±0.00 | +0.7% | — |
nii_resample_from_to |
6.19 ±0.00 | 6.23 ±0.00 | +0.7% | — |
nii_erode_msk |
5.87 ±0.00 | 5.86 ±0.00 | -0.2% | — |
… 30 more measurements
| Measurement | baseline MiB (median ±½·range) | head MiB (median ±½·range) | Δ % | p |
|---|---|---|---|---|
poi_to_global |
3.02 ±0.00 | 3.02 ±0.00 | +0.1% | — |
nii_center_of_masses |
3.21 ±0.00 | 3.21 ±0.00 | +0.1% | — |
nii_volumes |
3.46 ±0.00 | 3.46 ±0.00 | +0.1% | — |
nii_save |
3.64 ±0.00 | 3.64 ±0.00 | +0.1% | — |
poi_reorient |
3.77 ±0.00 | 3.77 ±0.00 | +0.1% | — |
nii_set_dtype |
5.24 ±0.00 | 5.24 ±0.00 | +0.1% | — |
nii_extract_label |
5.30 ±0.00 | 5.30 ±0.00 | +0.1% | — |
nii_pad_to |
5.36 ±0.00 | 5.36 ±0.00 | +0.1% | — |
nii_map_labels |
5.43 ±0.00 | 5.43 ±0.00 | +0.1% | — |
nii_apply_crop |
5.80 ±0.00 | 5.80 ±0.00 | +0.1% | — |
nii_dilate_msk |
5.86 ±0.00 | 5.87 ±0.00 | +0.1% | — |
nii_rescale_seg |
5.88 ±0.00 | 5.88 ±0.00 | +0.1% | — |
poi_calc_centroids_nocrop |
5.92 ±0.00 | 5.93 ±0.00 | +0.1% | — |
poi_calc_centroids |
5.99 ±0.00 | 5.99 ±0.00 | +0.1% | — |
nii_fill_holes |
6.21 ±0.00 | 6.22 ±0.00 | +0.1% | — |
nii_get_connected_components |
6.55 ±0.00 | 6.55 ±0.00 | +0.1% | — |
nii_filter_connected_components |
6.80 ±0.00 | 6.80 ±0.00 | +0.1% | — |
nii_load_img |
3.56 ±0.00 | 3.56 ±0.00 | +0.0% | — |
nii_load_seg |
5.94 ±0.00 | 5.94 ±0.00 | +0.0% | — |
metric_voxels |
3536.00 ±0.00 | 3536.00 ±0.00 | +0.0% | — |
metric_labels |
7.00 ±0.00 | 7.00 ±0.00 | +0.0% | — |
metric_foreground_pct |
50.17 ±0.00 | 50.17 ±0.00 | +0.0% | — |
poi_save |
1.39 ±0.00 | 1.40 ±0.00 | +0.3% (noise) | — |
poi_load |
1.55 ±0.00 | 1.55 ±0.00 | +0.3% (noise) | — |
nii_get_array |
1.58 ±0.00 | 1.59 ±0.00 | +0.2% (noise) | — |
poi_map_labels |
1.71 ±0.00 | 1.71 ±0.00 | +0.2% (noise) | — |
poi_rescale |
2.54 ±0.00 | 2.54 ±0.00 | +0.2% (noise) | — |
nii_compute_crop |
2.83 ±0.00 | 2.84 ±0.00 | +0.1% (noise) | — |
poi_local_to_global_arr |
2.89 ±0.00 | 2.89 ±0.00 | +0.1% (noise) | — |
nii_unique |
2.89 ±0.00 | 2.90 ±0.00 | +0.1% (noise) | — |
Gate: a measurement fails when the baseline is ≥ 1 MiB, the median grows by ≥ 50%, and Welch's t-test gives p < 0.05. metric_* rows are context only.
|
Suggestion: partition_segmentation_by_volume |
robert-graf
left a comment
There was a problem hiding this comment.
Rename and approved
split_label_at_cumulative_volume_fraction -> partition_segmentation_by_volume split_label_at_center_of_mass -> partition_segmentation_by_center_of_mass Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The CI linter installs the latest ruff, which now flags the unaliased import; the finding predates this branch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Upstreams the two reusable kernels hiding inside paraside's
split_ethmoid, which wrapped genericlogic around hard-coded ethmoid label ids (7/8/15/16) and offsets (+100/+200).
What's new
NII.split_label_at_cumulative_volume_fraction(labels, axis, fraction, offset)walks slices inwardsfrom the
axis-most end of a mask, summing voxels untilfractionof the total volume is covered,and adds
offsetto the labels of that slab. This is a volume fraction, not an extent fraction, soa structure that is thin at one end is not cut in the middle of its bounding box.
NII.split_label_at_center_of_mass(labels, axis, offset)cuts at the rounded center of mass alongaxisand offsets the labels on theaxisside of the plane.Changes from the source implementation
orientation, so the reorient round-trip theoriginal did (and the reorient back at the end) is gone. A raw array axis
intalso works.orientation the image is stored in. Rounding in the array frame shifted it by one slice when the
center of mass landed exactly on a voxel center.
arr[slab] += offsetfollowed byarr[arr == offset] = 0, which silently deletes any label equal to the offset. The dtype ispromoted when the offset would overflow it.
fraction=0yields an empty slab. The original had no such case: its loop leftcutoff_sliceasNonewhen the threshold was never reached and then crashed on an undefined variable.KeyError.Tests
12 tests in
unit_tests/test_nii_extended.py, including orientation invariance for both methods anda pipeline test that composes them back into the original ethmoid split — the result is
voxel-identical to
split_ethmoid.🤖 Generated with Claude Code
https://claude.ai/code/session_01GFZf44LHBB6N5jaf6YFzhx