Skip to content

feat(registration): DeepALI closed-form point reg + template pre-registration hook - #139

Merged
Hendrik-code merged 13 commits into
mainfrom
Point-Reg
Sep 2, 2026
Merged

feat(registration): DeepALI closed-form point reg + template pre-registration hook#139
Hendrik-code merged 13 commits into
mainfrom
Point-Reg

Conversation

@robert-graf

@robert-graf robert-graf commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a DeepALI-based closed-form rigid point registration, teaches General_Registration to work when fixed/moving live on different grids and to accept POI landmark sets directly, and introduces Template_Registration2 which composes those pieces so the atlas no longer has to be resampled between the rigid and deformable stages. Optional-dependency handling is tightened along the way and the whole subsystem is documented in CLAUDE_reg.md.

New public surface

  • Deepali_Point_Registration (_ridged_points/deepali_point_registration.py)
    • Kabsch/Horn SVD fit on paired POIs; result exposed as a DeepALI HomogeneousTransform on the target grid so it plugs directly into DeepALI pipelines.
    • Full parity with the SITK Point_Registration API: transform_nii, transform_poi, transform_poi_inverse, transform_cord(+inverse), get_affine, pickle save/load, apply() dispatch, deepali_transform property.
    • _horn_rigid handles the degenerate N == 1 case as a pure translation (R = I, t = q − p) instead of erroring out.
    • Helpers ridged_points_from_poi_deepali / ridged_points_from_subreg_vert_deepali mirroring the SITK counterparts.
  • General_Registration (_deepali/deepali_model.py)
    • New same_space=True flag (default = old behaviour). When False, transform_nii threads the true moving grid into TransformImage, so fixed and moving can differ in shape / spacing / orientation.
    • source_landmarks / target_landmarks now accept POI or POI_Global. Shared IDs are matched automatically and converted to target-grid cube-coordinate tensors for LandmarkPointDistance.
    • get_dump / load_ include the new flag; legacy 4-tuple dumps still load and default to same_space=True.
  • Template_Registration2 (_deformable/multilabel_segmentation.py)
    • Same shape as Template_Registration (rigid → deformable, optional crop, optional side-flip) but uses Deepali_Pod stage and accepts a pre_registration= argument. When supplied, no landmarks/centroids are computed internally.
    • save/load take gpu/ddevice so a round-trip on CPU no longer forces the deformable transform onto CUDA.

Refactor

  • Extracted a module-level _flip_r_axis(x) (with a _r_axis_slicer(axis) helper) in multilabel_segmentation.py. Replnching flip blocks in Template_Registration.init / transform_nii / transform_poi / transform_poi_inverse and the
    same pattern in Template_Registration2. Typed with a TypeVar so callers get their own subtype back; explicitly renstead of silently returning garbage — this fixed a latent bug in Template_Registration.transform_poi_inverse.

Optional-dependency UX

  • TPTBox.registration/init now imports each deepali-backed class in its own try/except. On failure a stub builtb / _make_missing_deepali_func replaces the name. Any use raises a clear ImportError with pip install torch
    hf-deepali. SITK Point_Registration stays fully usable when deepali is absent.
  • TPTBox.core.internal.elastic_deform.py no longer imports elasticdeform bare — it raises an ImportError whose messlled NumPy version at runtime and, on NumPy 2.x, prints the exact source-tarball command that fixes the broken PyPIwheel:
    pip install --no-binary :all: --no-build-isolation --force-reinstall --no-deps
    https://github.com/gvtulder/elasticdeform/archive/refs/tags/v0.5.1.tar.gz

Tests (unit_tests/test_registration_deepali.py)

27 tests, all pass on CPU in ~20 s:Deepali_Point_Registration — identity, translation, full-reorientation numerics; transform_nii matches ground trusform_poi_inverse round-trip; transform_cord/_inverse round-trip; apply() dispatch; deepali_transform type;save/load; too-few-points → ValueError at 0, translation at 1.General_Registration — same_space=False smoke, POI landmark shape/matching, real POI-driven landmark loss actuall) → source residual < 0.02 in cube coords), POI_Global path, save/load round-trip preserving same_space, legacy4-tuple load.

  • Template_Registration2 — pipeline w/ pre-registration, only_rigid=True, transform_poi, auto-fit path when pre_registration=None, save/load round-trip, and — using elasticdeform with fixed small params — a real "deformable stage improves overlap vs. rigid-only" assertion (IoU 0.74 → 0.98).
  • _flip_r_axis — involution on NII and voxel POI, R-axis is the only coordinate that changes, POI_Global explicitly
  • Optional-import stubs — pin the wording of the missing-deepali ImportError.
  • Speed / memory bench — logs a summary line comparing SITK vs. DeepALI on both fit and warp.

Benchmarks (CPU, py3.12)

┌─────────────────────────────┬─────────┬──────────┐
│ │ SITK │ Deepali │
├─────────────────────────────┼─────────┼──────────┤
│ fit (73³) │ ~7.3 ms │ ~1.4 ms │
├─────────────────────────────┼─────────┼──────────┤
│ warp (73³) │ ~9.6 ms │ ~19.7 ms │
├─────────────────────────────┼─────────┼──────────┤
│ fit (270×220×72) │ ~87 ms │ ~1.4 ms │
├─────────────────────────────┼─────────┼──────────┤
│ warp (270×220×72) │ ~131 ms │ ~243 ms │
├─────────────────────────────┼─────────┼──────────┤
│ mean voxel err (270×220×72) │ 6.53 │ 0.0002 │
└─────────────────────────────┴─────────┴──────────┘

Deepali's fit is ~5–60× faster (Kabsch stays constant with N); warp is 1.5–2× slower on CPU but drastically more accurate (SITK BSpline shows heavy ringing). GPU flips the warp comparison.

Non-goals / follow-ups

  • SITK Point_Registration still requires ≥ 2 landmarks (the single-point relaxation is DeepALI-only for now — LandmarkBasedTransformInitializer would need an equivalent manual fallback).
  • No user-facing changes to Rigid_Elements_Registration.

Test plan

  • pytest unit_tests/test_registration_deepali.py — 27 passed
  • ruff check TPTBox/registration/ TPTBox/core/internal/elastic_deform.py unit_tests/test_registration_deepali.p
  • Verified import graceful-degradation with deepali blocked on the meta path
  • Verified elasticdeform dynamic error message on both NumPy 1.x and 2.x branches

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Benchmark comparison

Speed (wall time per call)

baseline ab4d843 vs head ab4d843 · python 3.11.16 · 5 repeats + 1 warmup

Showing the 5 most-changed measurements per case; the rest are collapsed. Rows with a baseline below 3 ms are tagged (noise) — runner jitter on those swamps any real change.

ct_3d — shape (73, 47, 73)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_save 9.32 ±0.30 9.05 ±0.14 -2.9% 0.102
nii_rescale 31.23 ±0.14 31.96 ±0.68 +2.3% 0.053
nii_dilate_msk 95.88 ±0.20 93.96 ±0.42 -2.0% 0.000
nii_fill_holes 3.79 ±0.04 3.72 ±0.07 -1.6% 0.164
nii_load_img 9.35 ±0.09 9.22 ±0.03 -1.4% 0.077
… 31 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_erode_msk 4.90 ±0.05 4.84 ±0.06 -1.1% 0.178
poi_calc_centroids_nocrop 3.42 ±0.03 3.45 ±0.04 +1.0% 0.422
nii_filter_connected_components 3.36 ±0.04 3.33 ±0.05 -0.7% 0.368
nii_resample_from_to 32.57 ±0.14 32.66 ±0.56 +0.3% 0.251
poi_calc_poi_from_subreg_vert 9.12 ±0.16 9.12 ±0.11 -0.0% 0.431
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.05 ±0.01 0.03 ±0.00 -39.9% (noise) 0.000
nii_reorient 0.71 ±0.02 0.52 ±0.03 -26.7% (noise) 0.000
nii_extract_label 0.33 ±0.04 0.25 ±0.02 -23.6% (noise) 0.026
nii_pad_to 0.56 ±0.05 0.43 ±0.03 -23.5% (noise) 0.004
nii_apply_crop 0.59 ±0.06 0.47 ±0.06 -20.6% (noise) 0.015
nii_set_dtype 0.41 ±0.06 0.33 ±0.05 -19.3% (noise) 0.048
poi_to_global 0.14 ±0.01 0.16 ±0.01 +14.9% (noise) 0.018
poi_map_labels 0.13 ±0.01 0.12 ±0.01 -7.7% (noise) 0.321
nii_compute_crop 0.29 ±0.02 0.27 ±0.01 -7.7% (noise) 0.048
poi_resample_from_to 0.45 ±0.01 0.42 ±0.01 -7.1% (noise) 0.008
poi_local_to_global_arr 0.20 ±0.00 0.21 ±0.02 +6.0% (noise) 0.240
nii_map_labels 0.68 ±0.04 0.64 ±0.08 -5.4% (noise) 0.889
poi_load 0.69 ±0.01 0.67 ±0.02 -2.4% (noise) 0.062
poi_reorient 0.27 ±0.01 0.26 ±0.02 -2.2% (noise) 0.555
nii_center_of_masses 1.39 ±0.01 1.42 ±0.02 +1.9% (noise) 0.052
poi_rescale 0.14 ±0.00 0.14 ±0.01 -1.7% (noise) 0.926
nii_get_connected_components 1.61 ±0.09 1.58 ±0.02 -1.4% (noise) 0.156
nii_load_seg 2.39 ±0.07 2.35 ±0.08 -1.3% (noise) 0.663
poi_save 0.32 ±0.02 0.32 ±0.03 +1.1% (noise) 0.377
nii_unique 0.46 ±0.01 0.46 ±0.02 -0.9% (noise) 0.692
nii_rescale_seg 2.57 ±0.01 2.59 ±0.44 +0.8% (noise) 0.278
nii_volumes 1.52 ±0.02 1.51 ±0.04 -0.4% (noise) 0.808
poi_calc_centroids 1.92 ±0.03 1.92 ±0.04 -0.2% (noise) 0.910

ct_2d — shape (73, 47, 1)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_resample_from_to 6.02 ±0.17 5.67 ±0.18 -5.7% 0.101
nii_dilate_msk 11.10 ±0.13 10.80 ±0.05 -2.7% 0.003
nii_rescale 4.47 ±0.15 4.49 ±0.19 +0.3% 0.979
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%
poi_to_global 0.25 ±0.01 0.22 ±0.01 -11.0% (noise) 0.002
poi_resample_from_to 0.67 ±0.04 0.61 ±0.01 -9.5% (noise) 0.031
nii_unique 0.13 ±0.00 0.12 ±0.01 -9.0% (noise) 0.016
nii_reorient 0.68 ±0.02 0.74 ±0.04 +8.3% (noise) 0.052
poi_save 0.47 ±0.04 0.44 ±0.02 -8.3% (noise) 0.114
nii_extract_label 0.40 ±0.01 0.37 ±0.01 -8.2% (noise) 0.001
poi_calc_centroids_nocrop 0.97 ±0.03 0.90 ±0.02 -6.9% (noise) 0.004
nii_get_connected_components 0.61 ±0.02 0.57 ±0.08 -6.7% (noise) 0.733
poi_map_labels 0.20 ±0.01 0.19 ±0.00 -6.5% (noise) 0.001
nii_save 1.14 ±0.06 1.21 ±0.05 +6.3% (noise) 0.293
nii_erode_msk 0.83 ±0.03 0.78 ±0.02 -6.1% (noise) 0.031
poi_calc_centroids 0.82 ±0.02 0.77 ±0.02 -5.6% (noise) 0.006
nii_center_of_masses 0.20 ±0.00 0.19 ±0.01 -4.9% (noise) 0.019
poi_local_to_global_arr 0.23 ±0.00 0.25 ±0.01 +4.5% (noise) 0.039
nii_fill_holes 0.74 ±0.01 0.70 ±0.01 -4.3% (noise) 0.002
nii_load_seg 1.45 ±0.06 1.39 ±0.03 -3.9% (noise) 0.028
poi_rescale 0.23 ±0.01 0.22 ±0.01 -3.6% (noise) 0.075
nii_apply_crop 0.62 ±0.02 0.61 ±0.01 -2.9% (noise) 0.051
nii_get_array 0.02 ±0.00 0.02 ±0.01 -2.8% (noise) 0.643
poi_reorient 0.39 ±0.01 0.40 ±0.01 +2.3% (noise) 0.012
nii_map_labels 0.45 ±0.02 0.44 ±0.02 -2.1% (noise) 0.791
nii_pad_to 0.51 ±0.05 0.52 ±0.01 +1.8% (noise) 0.838
nii_volumes 0.26 ±0.45 0.26 ±0.01 -1.8% (noise) 0.367
nii_load_img 1.22 ±0.05 1.20 ±0.05 -1.4% (noise) 0.594
nii_set_dtype 0.38 ±0.02 0.38 ±0.01 -1.4% (noise) 0.683
nii_rescale_seg 0.68 ±0.02 0.69 ±0.04 +1.3% (noise) 0.456
nii_compute_crop 0.14 ±0.00 0.14 ±0.01 -1.1% (noise) 0.396
poi_load 0.82 ±0.01 0.81 ±0.01 -0.8% (noise) 0.349
nii_filter_connected_components 0.79 ±0.03 0.79 ±0.12 -0.7% (noise) 0.651

mri_3d — shape (68, 52, 67)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_fill_holes 4.83 ±0.09 4.71 ±0.03 -2.4% 0.046
nii_dilate_msk 124.20 ±0.47 121.33 ±0.82 -2.3% 0.001
nii_load_img 7.45 ±0.06 7.55 ±0.05 +1.3% 0.178
nii_save 7.50 ±0.06 7.45 ±0.06 -0.7% 0.122
nii_resample_from_to 30.60 ±0.39 30.42 ±0.13 -0.6% 0.282
… 31 more measurements
Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
poi_calc_poi_from_subreg_vert 8.49 ±0.12 8.54 ±0.09 +0.6% 0.954
nii_rescale 29.21 ±0.10 29.07 ±0.10 -0.5% 0.167
nii_filter_connected_components 3.67 ±0.04 3.66 ±0.04 -0.4% 0.508
nii_erode_msk 6.39 ±0.19 6.41 ±0.04 +0.3% 0.880
poi_calc_centroids_nocrop 7.13 ±0.02 7.14 ±0.06 +0.1% 0.379
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 0.50 ±0.01 0.48 ±0.01 -5.4% (noise) 0.017
poi_map_labels 0.22 ±0.00 0.21 ±0.00 -5.4% (noise) 0.000
nii_extract_label 0.42 ±0.01 0.41 ±0.01 -2.6% (noise) 0.236
nii_unique 0.51 ±0.02 0.50 ±0.01 -2.5% (noise) 0.305
nii_get_array 0.05 ±0.00 0.05 ±0.00 +2.4% (noise) 0.178
nii_reorient 0.76 ±0.04 0.75 ±0.01 -2.3% (noise) 0.487
poi_resample_from_to 0.66 ±0.01 0.64 ±0.02 -2.3% (noise) 0.116
poi_local_to_global_arr 0.25 ±0.01 0.25 ±0.04 +1.9% (noise) 0.273
nii_rescale_seg 2.51 ±0.05 2.46 ±0.03 -1.7% (noise) 0.128
nii_load_seg 2.26 ±0.11 2.29 ±0.04 +1.6% (noise) 0.631
nii_get_connected_components 1.67 ±0.02 1.70 ±0.03 +1.6% (noise) 0.260
poi_reorient 0.43 ±0.02 0.42 ±0.01 -1.4% (noise) 0.177
nii_set_dtype 0.47 ±0.03 0.46 ±0.02 -1.3% (noise) 0.448
poi_to_global 0.25 ±0.01 0.25 ±0.01 +1.1% (noise) 0.815
poi_rescale 0.26 ±0.01 0.26 ±0.01 +0.9% (noise) 0.586
nii_map_labels 0.83 ±0.02 0.84 ±0.02 +0.9% (noise) 0.937
nii_volumes 1.64 ±0.02 1.63 ±0.01 -0.7% (noise) 0.098
nii_compute_crop 0.32 ±0.00 0.32 ±0.01 +0.6% (noise) 0.934
poi_calc_centroids 2.27 ±0.02 2.28 ±0.01 +0.5% (noise) 0.645
nii_apply_crop 0.62 ±0.01 0.62 ±0.01 +0.4% (noise) 0.820
poi_load 1.67 ±0.01 1.66 ±0.02 -0.2% (noise) 0.917
nii_pad_to 0.65 ±0.02 0.65 ±0.02 +0.2% (noise) 1.000
nii_center_of_masses 1.65 ±0.01 1.65 ±0.01 -0.1% (noise) 0.163

mri_2d — shape (68, 52, 1)

Measurement baseline ms (median ±½·range) head ms (median ±½·range) Δ % p
nii_rescale 4.52 ±0.20 4.25 ±0.03 -5.9% 0.144
nii_resample_from_to 5.82 ±0.16 5.59 ±0.08 -4.0% 0.111
nii_dilate_msk 14.69 ±0.13 14.16 ±0.10 -3.6% 0.000
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_get_array 0.02 ±0.00 0.02 ±0.00 -12.2% (noise) 0.115
nii_set_dtype 0.39 ±0.03 0.36 ±0.01 -9.0% (noise) 0.062
nii_pad_to 0.53 ±0.03 0.49 ±0.01 -6.4% (noise) 0.020
nii_apply_crop 0.61 ±0.03 0.58 ±0.01 -6.2% (noise) 0.033
nii_rescale_seg 0.70 ±0.04 0.66 ±0.01 -5.5% (noise) 0.072
poi_save 0.50 ±0.03 0.48 ±0.01 -5.0% (noise) 0.090
nii_save 1.20 ±0.03 1.15 ±0.02 -4.2% (noise) 0.023
nii_load_img 1.23 ±0.04 1.18 ±0.03 -4.0% (noise) 0.028
nii_volumes 0.39 ±0.01 0.38 ±0.01 -4.0% (noise) 0.008
nii_fill_holes 0.87 ±0.02 0.84 ±0.01 -3.5% (noise) 0.038
poi_calc_centroids_nocrop 1.14 ±0.04 1.10 ±0.02 -3.5% (noise) 0.036
poi_reorient 0.43 ±0.03 0.42 ±0.01 -3.1% (noise) 0.539
nii_map_labels 0.45 ±0.03 0.44 ±0.01 -3.1% (noise) 0.735
poi_map_labels 0.22 ±0.00 0.22 ±0.01 +3.0% (noise) 0.070
poi_load 1.51 ±0.02 1.56 ±0.12 +3.0% (noise) 0.138
nii_unique 0.13 ±0.01 0.12 ±0.01 -2.7% (noise) 0.421
nii_erode_msk 1.00 ±0.02 0.97 ±0.05 -2.7% (noise) 0.842
poi_calc_centroids 0.95 ±0.02 0.92 ±0.01 -2.6% (noise) 0.054
nii_extract_label 0.38 ±0.01 0.37 ±0.02 -2.1% (noise) 0.075
poi_resample_from_to 0.64 ±0.03 0.63 ±0.02 -1.7% (noise) 0.574
poi_to_global 0.25 ±0.01 0.25 ±0.01 -1.6% (noise) 0.094
poi_local_to_global_arr 0.24 ±0.00 0.25 ±0.01 +1.4% (noise) 0.119
nii_reorient 0.69 ±0.02 0.68 ±0.02 -1.3% (noise) 0.323
nii_compute_crop 0.13 ±0.01 0.13 ±0.01 +0.9% (noise) 0.615
nii_load_seg 1.34 ±0.05 1.35 ±0.03 +0.8% (noise) 0.444
nii_get_connected_components 0.58 ±0.03 0.58 ±0.02 -0.7% (noise) 0.459
poi_rescale 0.26 ±0.02 0.26 ±0.02 -0.7% (noise) 0.823
nii_filter_connected_components 0.75 ±0.01 0.75 ±0.01 +0.3% (noise) 0.967
nii_center_of_masses 0.34 ±0.01 0.33 ±0.01 -0.1% (noise) 0.825

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 ab4d843 vs head ab4d843 · python 3.11.16 · 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
nii_fill_holes 6.41 ±0.00 6.45 ±0.00 +0.7%
nii_load_img 3.56 ±0.00 3.57 ±0.00 +0.1%
nii_save 3.84 ±0.00 3.84 ±0.00 +0.1%
nii_load_seg 6.07 ±0.00 6.07 ±0.00 +0.1%
poi_calc_poi_from_subreg_vert 7.30 ±0.00 7.30 ±0.00 -0.1%
… 31 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_set_dtype 5.37 ±0.00 5.37 ±0.00 +0.0%
nii_reorient 5.97 ±0.00 5.97 ±0.00 +0.0%
nii_rescale 6.42 ±0.00 6.42 ±0.00 +0.0%
nii_rescale_seg 6.18 ±0.00 6.18 ±0.00 +0.0%
nii_resample_from_to 6.55 ±0.00 6.55 ±0.00 +0.0%
nii_apply_crop 5.93 ±0.00 5.93 ±0.00 +0.0%
nii_pad_to 5.49 ±0.00 5.49 ±0.00 +0.0%
nii_volumes 3.52 ±0.00 3.52 ±0.00 +0.0%
nii_center_of_masses 3.21 ±0.00 3.21 ±0.00 +0.0%
nii_extract_label 5.49 ±0.00 5.49 ±0.00 +0.0%
nii_map_labels 5.55 ±0.00 5.55 ±0.00 +0.0%
nii_dilate_msk 6.05 ±0.00 6.05 ±0.00 +0.0%
nii_erode_msk 6.07 ±0.00 6.07 ±0.00 +0.0%
nii_get_connected_components 6.68 ±0.00 6.68 ±0.00 +0.0%
nii_filter_connected_components 6.99 ±0.00 6.99 ±0.00 +0.0%
poi_calc_centroids 6.18 ±0.00 6.18 ±0.00 +0.0%
poi_calc_centroids_nocrop 6.05 ±0.00 6.05 ±0.00 +0.0%
poi_reorient 3.89 ±0.00 3.89 ±0.00 +0.0%
poi_to_global 3.14 ±0.00 3.14 ±0.00 +0.0%
poi_local_to_global_arr 3.02 ±0.00 3.02 ±0.00 +0.0%
poi_resample_from_to 5.53 ±0.00 5.53 ±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%
nii_get_array 1.65 ±0.00 1.65 ±0.00 +0.0% (noise)
nii_compute_crop 2.96 ±0.00 2.96 ±0.00 +0.0% (noise)
nii_unique 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
poi_rescale 2.61 ±0.00 2.61 ±0.00 +0.0% (noise)
poi_save 1.46 ±0.00 1.46 ±0.00 +0.0% (noise)
poi_map_labels 1.77 ±0.00 1.77 ±0.00 +0.0% (noise)
poi_load 1.61 ±0.00 1.61 ±0.00 +0.0% (noise)

ct_2d — shape (73, 47, 1)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_fill_holes 6.35 ±0.00 6.39 ±0.00 +0.7%
nii_load_img 3.50 ±0.00 3.50 ±0.00 +0.1%
nii_save 3.77 ±0.00 3.78 ±0.00 +0.1%
nii_load_seg 6.01 ±0.00 6.01 ±0.00 +0.1%
nii_set_dtype 5.30 ±0.00 5.30 ±0.00 +0.0%
… 30 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_reorient 5.91 ±0.00 5.91 ±0.00 +0.0%
nii_rescale 6.36 ±0.00 6.36 ±0.00 +0.0%
nii_rescale_seg 6.12 ±0.00 6.12 ±0.00 +0.0%
nii_resample_from_to 6.48 ±0.00 6.48 ±0.00 +0.0%
nii_apply_crop 5.87 ±0.00 5.87 ±0.00 +0.0%
nii_pad_to 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_volumes 3.46 ±0.00 3.46 ±0.00 +0.0%
nii_center_of_masses 3.15 ±0.00 3.15 ±0.00 +0.0%
nii_extract_label 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_map_labels 5.49 ±0.00 5.49 ±0.00 +0.0%
nii_dilate_msk 5.99 ±0.00 5.99 ±0.00 +0.0%
nii_erode_msk 6.01 ±0.00 6.01 ±0.00 +0.0%
nii_get_connected_components 6.62 ±0.00 6.62 ±0.00 +0.0%
nii_filter_connected_components 6.93 ±0.00 6.93 ±0.00 +0.0%
poi_calc_centroids 6.12 ±0.00 6.12 ±0.00 +0.0%
poi_calc_centroids_nocrop 6.05 ±0.00 6.05 ±0.00 +0.0%
poi_reorient 3.83 ±0.00 3.83 ±0.00 +0.0%
poi_to_global 3.08 ±0.00 3.08 ±0.00 +0.0%
poi_resample_from_to 5.46 ±0.00 5.46 ±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%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
nii_unique 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.96 ±0.00 2.96 ±0.00 +0.0% (noise)
poi_save 1.40 ±0.00 1.40 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (noise)

mri_3d — shape (68, 52, 67)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_fill_holes 6.35 ±0.00 6.39 ±0.00 +0.7%
poi_calc_centroids 6.12 ±0.00 6.12 ±0.00 -0.1%
nii_volumes 3.47 ±0.00 3.46 ±0.00 -0.1%
nii_load_img 3.56 ±0.00 3.57 ±0.00 +0.1%
nii_save 3.77 ±0.00 3.78 ±0.00 +0.1%
… 31 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_load_seg 6.01 ±0.00 6.01 ±0.00 +0.1%
nii_set_dtype 5.37 ±0.00 5.37 ±0.00 +0.0%
nii_reorient 5.91 ±0.00 5.91 ±0.00 +0.0%
nii_rescale 6.36 ±0.00 6.36 ±0.00 +0.0%
nii_rescale_seg 6.12 ±0.00 6.12 ±0.00 +0.0%
nii_resample_from_to 6.48 ±0.00 6.48 ±0.00 +0.0%
nii_apply_crop 5.87 ±0.00 5.87 ±0.00 +0.0%
nii_pad_to 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_center_of_masses 3.15 ±0.00 3.15 ±0.00 +0.0%
nii_extract_label 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_map_labels 5.49 ±0.00 5.49 ±0.00 +0.0%
nii_dilate_msk 5.99 ±0.00 5.99 ±0.00 +0.0%
nii_erode_msk 6.01 ±0.00 6.01 ±0.00 +0.0%
nii_get_connected_components 6.62 ±0.00 6.62 ±0.00 +0.0%
nii_filter_connected_components 6.93 ±0.00 6.93 ±0.00 +0.0%
poi_calc_centroids_nocrop 5.99 ±0.00 5.99 ±0.00 +0.0%
poi_reorient 3.83 ±0.00 3.83 ±0.00 +0.0%
poi_to_global 3.08 ±0.00 3.08 ±0.00 +0.0%
poi_resample_from_to 5.46 ±0.00 5.46 ±0.00 +0.0%
poi_calc_poi_from_subreg_vert 7.30 ±0.00 7.30 ±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%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
nii_unique 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.96 ±0.00 2.96 ±0.00 +0.0% (noise)
poi_save 1.46 ±0.00 1.46 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (noise)

mri_2d — shape (68, 52, 1)

Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_fill_holes 6.35 ±0.00 6.39 ±0.00 +0.7%
nii_load_img 3.56 ±0.00 3.57 ±0.00 +0.1%
nii_save 3.77 ±0.00 3.78 ±0.00 +0.1%
nii_load_seg 6.01 ±0.00 6.01 ±0.00 +0.1%
nii_set_dtype 5.37 ±0.00 5.37 ±0.00 +0.0%
… 30 more measurements
Measurement baseline MiB (median ±½·range) head MiB (median ±½·range) Δ % p
nii_reorient 5.91 ±0.00 5.91 ±0.00 +0.0%
nii_rescale 6.36 ±0.00 6.36 ±0.00 +0.0%
nii_rescale_seg 6.12 ±0.00 6.12 ±0.00 +0.0%
nii_resample_from_to 6.48 ±0.00 6.48 ±0.00 +0.0%
nii_apply_crop 5.87 ±0.00 5.87 ±0.00 +0.0%
nii_pad_to 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_volumes 3.46 ±0.00 3.46 ±0.00 +0.0%
nii_center_of_masses 3.15 ±0.00 3.15 ±0.00 +0.0%
nii_extract_label 5.43 ±0.00 5.43 ±0.00 +0.0%
nii_map_labels 5.49 ±0.00 5.49 ±0.00 +0.0%
nii_dilate_msk 5.99 ±0.00 5.99 ±0.00 +0.0%
nii_erode_msk 6.01 ±0.00 6.01 ±0.00 +0.0%
nii_get_connected_components 6.62 ±0.00 6.62 ±0.00 +0.0%
nii_filter_connected_components 6.93 ±0.00 6.93 ±0.00 +0.0%
poi_calc_centroids 6.12 ±0.00 6.12 ±0.00 +0.0%
poi_calc_centroids_nocrop 6.05 ±0.00 6.05 ±0.00 +0.0%
poi_reorient 3.83 ±0.00 3.83 ±0.00 +0.0%
poi_to_global 3.08 ±0.00 3.08 ±0.00 +0.0%
poi_resample_from_to 5.46 ±0.00 5.46 ±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%
nii_get_array 1.59 ±0.00 1.59 ±0.00 +0.0% (noise)
nii_compute_crop 2.90 ±0.00 2.90 ±0.00 +0.0% (noise)
nii_unique 2.84 ±0.00 2.84 ±0.00 +0.0% (noise)
poi_rescale 2.54 ±0.00 2.54 ±0.00 +0.0% (noise)
poi_local_to_global_arr 2.96 ±0.00 2.96 ±0.00 +0.0% (noise)
poi_save 1.46 ±0.00 1.46 ±0.00 +0.0% (noise)
poi_map_labels 1.71 ±0.00 1.71 ±0.00 +0.0% (noise)
poi_load 1.55 ±0.00 1.55 ±0.00 +0.0% (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.

@robert-graf robert-graf self-assigned this Aug 28, 2026
@robert-graf robert-graf added the enhancement New feature or request label Aug 28, 2026
@Hendrik-code
Hendrik-code merged commit 80e9de9 into main Sep 2, 2026
6 checks passed
@Hendrik-code
Hendrik-code deleted the Point-Reg branch September 2, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants