Skip to content

Commit f3bf2f8

Browse files
authored
fix: replace absolute intra-package imports with relative imports (#67)
* fix: replace absolute intra-package imports with relative imports All submodules imported `from physiomotion4d.X import Y` (or `from physiomotion4d import Y`), which causes a circular import error at package initialization time — `__init__.py` imports each submodule while the submodules try to reach back into the partially-initialized package. This fails consistently regardless of install method (pip install ., editable install, or PyPI wheel). Replaced all 34 affected files with PEP 328 relative imports (`from .X import Y` for package submodules, `from ..X import Y` for the cli/ sub-package). Docstring examples left unchanged. * BUG: Affine transform mask when pre-transforming moving image * BUG: Fixed enum name
1 parent c792bb1 commit f3bf2f8

41 files changed

Lines changed: 218 additions & 241 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/cli_scripts/fit_statistical_model_to_patient.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The registration pipeline consists of four stages:
1616

1717
1. **ICP Alignment**: Rigid/affine alignment using surface matching
1818
2. **PCA Registration** (optional): Statistical shape model fitting
19-
3. **Mask-to-Mask Registration**: Deformable registration using distance maps
19+
3. **Mask-to-Mask Registration**: Greedy affine + ICON deformable registration using distance maps
2020
4. **Mask-to-Image Refinement** (optional): Final intensity-based refinement
2121

2222
Installation
@@ -120,7 +120,9 @@ Registration Configuration
120120
``--template-labelmap`` and template label IDs. Disabled by default.
121121

122122
``--use-ICON-refinement``
123-
Enable ICON deep learning registration refinement (default: disabled)
123+
Enable ICON deep learning refinement in the mask-to-image stage (Stage 4).
124+
The mask-to-mask stage always uses Greedy affine + ICON deformable.
125+
Default: disabled
124126

125127
Output Options
126128
--------------

experiments/Heart-Create_Statistical_Model/3-registration_based_correspondence.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
# %% [markdown]
33
# # Registration-Based Correspondence
44
#
5-
# This notebook aligns ICP-aligned models from step 2 to the average surface using **ANTs SyN (Symmetric Normalization)** deformable registration via mask-based registration.
5+
# This notebook aligns ICP-aligned models from step 2 to the average surface using **Greedy affine + ICON deformable** registration via mask-based registration.
66
#
77
# **Workflow:**
88
# 1. Load ICP-aligned models from `kcl-heart-model/surfaces_aligned/`
99
# 2. Load average surface (`average_surface.vtp`)
10-
# 3. Use `RegisterModelsDistanceMaps` to perform ANTs SyN deformable registration
10+
# 3. Use `RegisterModelsDistanceMaps` to perform Greedy affine + ICON deformable registration
1111
# 4. Save corresponded models to `kcl-heart-model/surfaces_aligned_corresponded/`
1212
# 5. Visualize before/after comparisons
1313
# 6. Analyze deformation magnitude and registration statistics
1414
#
1515
# **Method:**
16-
# - **ANTs SyN** provides diffeomorphic (smooth, invertible) deformation fields
17-
# - Progressive registration stages: rigid → affine → SyN deformable
16+
# - **Greedy** performs fast CPU-based affine pre-alignment
17+
# - **ICON** provides deep learning deformable registration on the affine-pre-aligned masks
1818
# - Mask-based approach focuses registration on the anatomical structures
1919

2020
# %%
@@ -110,11 +110,9 @@
110110
roi_dilation_mm=20.0, # Dilation for ROI mask
111111
)
112112

113-
# Perform ANTs SyN deformable registration
114-
# This performs progressive multi-stage registration: rigid → affine → SyN deformable
113+
# Perform Greedy affine + ICON deformable registration
115114
result = registrar.register(
116-
transform_type="Deformable", # Uses ANTs SyN (Symmetric Normalization)
117-
use_ICON=False, # Set to True for additional ICON deep learning refinement
115+
transform_type="Deformable",
118116
)
119117

120118
forward_transform = result["forward_transform"]
@@ -203,7 +201,7 @@
203201
plotter.show_axes()
204202
plotter.camera_position = "iso"
205203

206-
# Right: After distance map registration (ICP + ANTs SyN)
204+
# Right: After distance map registration (Greedy affine + ICON deformable)
207205
plotter.subplot(0, 1)
208206
plotter.add_mesh(
209207
fixed_model, color="lightblue", opacity=1.0, label="Average Surface"
@@ -212,7 +210,7 @@
212210
after_mesh, color="green", opacity=1.0, label=f"Case {case_id} (Corresponded)"
213211
)
214212
plotter.add_text(
215-
f"After Distance Map Registration (ANTs SyN)\nCase {case_id}",
213+
f"After Distance Map Registration (Greedy + ICON)\nCase {case_id}",
216214
position="upper_left",
217215
font_size=10,
218216
)
@@ -329,18 +327,16 @@
329327
# %% [markdown]
330328
# ## Summary
331329
#
332-
# This notebook performed mask-based deformable registration using **ANTs SyN (Symmetric Normalization)** to establish correspondence between the ICP-aligned models and the average surface.
330+
# This notebook performed mask-based deformable registration using **Greedy affine + ICON deformable** to establish correspondence between the ICP-aligned models and the average surface.
333331
#
334332
# **Next Steps:**
335333
# - Proceed to step 4: `4-surfaces_aligned_correspond_to_pca_inputs.ipynb` to prepare data for PCA analysis
336334
# - The corresponded models in `kcl-heart-model/surfaces_aligned_corresponded/` now have improved point-to-point correspondence
337335
# - The registration statistics show the deformation applied to each model
338336
#
339337
# **Registration Details:**
340-
# - The `RegisterModelsDistanceMaps` class uses **ANTs SyN** for progressive registration:
341-
# 1. Rigid alignment
342-
# 2. Affine transformation
343-
# 3. SyN deformable registration (diffeomorphic)
344-
# - Setting `use_ICON=True` in the `register()` call would add ICON deep learning refinement after SyN
338+
# - The `RegisterModelsDistanceMaps` class uses a two-stage pipeline:
339+
# 1. **Greedy affine** registration (fast CPU-based alignment)
340+
# 2. **ICON deformable** registration on the affine-pre-aligned masks (deep learning)
345341
# - The `roi_dilation_mm` parameter controls the dilation of the ROI mask (default 20mm)
346-
# - SyN registration provides smooth, invertible deformation fields for anatomical correspondence
342+
# - Composed Greedy + ICON transforms provide smooth, invertible deformation fields for anatomical correspondence

experiments/Heart-Create_Statistical_Model/README.md

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ This experiment follows a fully automated multi-step process. Each step is a
5151
- Prepares aligned data for correspondence computation
5252

5353
3. **`3-registration_based_correspondence.py`**
54-
- Establishes point correspondences across the population using ANTs SyN deformable registration
54+
- Establishes point correspondences across the population using Greedy affine + ICON deformable registration
5555
- Uses mask-based distance map registration via `RegisterModelsDistanceMaps`
56-
- Performs diffeomorphic (smooth, invertible) deformation to the average surface
56+
- Greedy affine pre-aligns masks; ICON deep learning refines with a deformable field
5757
- Critical step for meaningful PCA analysis
5858

5959
4. **`4-surfaces_aligned_correspond_to_pca_inputs.py`**
@@ -75,15 +75,15 @@ This experiment uses a fully automated approach combining:
7575

7676
Instead of traditional mesh parameterization methods (e.g., SPHARM-PDM), this pipeline uses **deformable image registration** to establish correspondences:
7777

78-
- **ANTs SyN (Symmetric Normalization)** performs diffeomorphic registration
78+
- **Greedy affine** (PICSL Greedy) performs fast CPU-based affine pre-alignment
79+
- **ICON deformable** applies deep learning registration on the affine-pre-aligned masks
7980
- Distance maps from surface meshes create continuous fields for registration
80-
- Progressive registration stages: rigid → affine → SyN deformable
8181
- Mask-based approach focuses registration on anatomical structures
8282

8383
**Advantages:**
8484
- Fully automated (no manual parameter tuning)
8585
- Handles complex topologies naturally
86-
- Diffeomorphic guarantees smooth, invertible deformations
86+
- Composed Greedy + ICON transforms provide smooth, invertible deformation fields
8787
- Integrates seamlessly with medical imaging pipelines
8888

8989
### PCA Computation
@@ -108,12 +108,12 @@ cd experiments/Heart-Create_Statistical_Model/
108108
# in VS Code or Cursor via the `# %%` cell markers):
109109
python 1-input_meshes_to_input_surfaces.py # Extract surfaces from volumetric meshes
110110
python 2-input_surfaces_to_surfaces_aligned.py # Rigid ICP alignment + compute average
111-
python 3-registration_based_correspondence.py # ANTs SyN deformable correspondence
111+
python 3-registration_based_correspondence.py # Greedy affine + ICON deformable correspondence
112112
python 4-surfaces_aligned_correspond_to_pca_inputs.py # Prepare PCA input matrices
113113
python 5-compute_pca_model.py # Compute PCA and export JSON model
114114
```
115115

116-
**Total Runtime:** Approximately 2-4 hours depending on hardware (20 heart meshes, ANTs registration is computationally intensive).
116+
**Total Runtime:** Approximately 1-3 hours depending on hardware (20 heart meshes; Greedy affine is fast on CPU, ICON requires a GPU for reasonable speed).
117117

118118
## Outputs
119119

@@ -167,7 +167,7 @@ registered_mesh = workflow.run_workflow()
167167
- VS Code or Cursor with the Python extension for cell-by-cell execution
168168
(optional; scripts also run end-to-end as plain Python)
169169
- ITK, VTK, PyVista (included with PhysioMotion4D)
170-
- ANTs (Advanced Normalization Tools) - installed automatically with PhysioMotion4D
170+
- picsl-greedy and ICON (included with PhysioMotion4D)
171171
- scikit-learn for PCA computation
172172

173173
### Data
@@ -176,19 +176,19 @@ registered_mesh = workflow.run_workflow()
176176
- ~2GB for final outputs
177177

178178
### Compute
179-
- CPU: Multi-core processor (8+ cores recommended for ANTs registration)
179+
- CPU: Multi-core processor (4+ cores recommended for Greedy affine registration)
180180
- RAM: 16GB minimum (32GB recommended)
181-
- GPU: Not required for this experiment
182-
- Time: ~2-4 hours total (ANTs deformable registration is computationally intensive)
181+
- GPU: Recommended for ICON deformable registration (CUDA-capable GPU)
182+
- Time: ~1-3 hours total (Greedy is fast; ICON speed depends on GPU availability)
183183

184184
## Citation
185185

186186
If you use this experiment or the KCL dataset, please cite:
187187

188188
> Rodero et al. (2021), "Linking statistical shape models and simulated function in the healthy adult human heart". *PLOS Computational Biology*. DOI: [10.1371/journal.pcbi.1008851](https://doi.org/10.1371/journal.pcbi.1008851)
189189
190-
For ANTs registration:
191-
> Avants BB, et al. (2011). "A reproducible evaluation of ANTs similarity metric performance in brain image registration". *NeuroImage*. DOI: [10.1016/j.neuroimage.2010.09.025](https://doi.org/10.1016/j.neuroimage.2010.09.025)
190+
For ICON registration:
191+
> Greer et al. (2021). "ICON: Learning Regular Maps Through Inverse Consistency". *ICCV*. DOI: [10.1109/ICCV48922.2021.00129](https://doi.org/10.1109/ICCV48922.2021.00129)
192192
193193
## Related Experiments
194194

@@ -199,7 +199,7 @@ For ANTs registration:
199199
## Support and Resources
200200

201201
- **KCL Dataset**: [https://zenodo.org/records/4590294](https://zenodo.org/records/4590294)
202-
- **ANTs Documentation**: [https://github.com/ANTsX/ANTs](https://github.com/ANTsX/ANTs)
202+
- **Greedy Documentation**: [https://greedy.readthedocs.io/](https://greedy.readthedocs.io/)
203203
- **PhysioMotion4D Documentation**: See main repository README and API documentation
204204
- **Issues**: Report bugs or request features on the PhysioMotion4D GitHub repository
205205

@@ -210,27 +210,25 @@ For ANTs registration:
210210
- Check `data/KCL-Heart-Model/README.md` for download instructions
211211
- Verify all 20 heart mesh files (`.vtk` format) are present
212212

213-
### ANTs Registration Taking Too Long
214-
- ANTs SyN registration is computationally intensive (5-15 minutes per subject)
215-
- Total time for 20 subjects: 2-4 hours is normal
216-
- Consider using a machine with more CPU cores
217-
- Progress is saved incrementally - can resume if interrupted
213+
### Registration Taking Too Long
214+
- Greedy affine is fast (< 1 minute per subject on CPU)
215+
- ICON deformable is GPU-accelerated; without a GPU it falls back to CPU and will be significantly slower
216+
- Total time for 20 subjects: 1-3 hours depending on GPU availability
218217

219218
### Memory Issues
220219
- Close other applications to free RAM
221-
- ANTs registration can use 4-8GB per process
220+
- ICON can use 4-8GB GPU VRAM; reduce batch size or iterations if needed
222221
- Process fewer meshes initially to test pipeline
223-
- Use a machine with more RAM (32GB+ recommended)
224222

225223
### Correspondence Quality Issues
226224
- Check alignment quality from step 2 (ICP should produce good initial alignment)
227225
- Verify average surface looks reasonable before step 3
228-
- ANTs parameters are pre-tuned for cardiac anatomy
229-
- If registration fails, check input mesh quality and topology
226+
- If Greedy affine fails, check input mesh quality and topology
227+
- If ICON deformable quality is poor, increase `icon_iterations` in the `register()` call
230228

231229
### Import Errors
232230
- Ensure all PhysioMotion4D dependencies are installed
233-
- Check that ANTs is available: `python -c "import ants; print(ants.__version__)"`
231+
- Check Greedy is available: `python -c "from picsl_greedy import Greedy3D; print('ok')"`
234232
- Reinstall environment if needed: `pip install -e .` in repository root
235233

236234
---

experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@
190190
# Perform deformable registration
191191
print("Starting deformable mask-to-mask registration...")
192192

193-
m2m_results = registrar.register_mask_to_mask(use_ICON_refinement=False)
193+
m2m_results = registrar.register_mask_to_mask()
194194
m2m_inverse_transform = m2m_results["inverse_transform"]
195195
m2m_forward_transform = m2m_results["forward_transform"]
196196
m2m_model_surface = m2m_results["registered_template_model_surface"]

src/physiomotion4d/cli/convert_image_4d_to_3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def main() -> int:
7070
print(f"Error: input image not found: {args.input_image}")
7171
return 1
7272
try:
73-
from physiomotion4d import ConvertImage4DTo3D
73+
from .. import ConvertImage4DTo3D
7474

7575
converter = ConvertImage4DTo3D()
7676
print(f"Loading 4D image: {args.input_image}")

src/physiomotion4d/cli/convert_image_to_usd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def main() -> int:
110110
# Initialize processor
111111
print("Initializing Image-to-USD processor...")
112112
try:
113-
from physiomotion4d import WorkflowConvertImageToUSD
113+
from .. import WorkflowConvertImageToUSD
114114

115115
processor = WorkflowConvertImageToUSD(
116116
input_filenames=args.input_files,

src/physiomotion4d/cli/convert_image_to_vtk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def main() -> int:
160160
print("=" * 70)
161161

162162
try:
163-
from physiomotion4d import WorkflowConvertImageToVTK
163+
from .. import WorkflowConvertImageToVTK
164164

165165
workflow = WorkflowConvertImageToVTK(
166166
segmentation_method=args.segmentation_method,

src/physiomotion4d/cli/convert_vtk_to_usd.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import os
1212
import sys
1313

14-
from physiomotion4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS
14+
from ..usd_anatomy_tools import DEFAULT_RENDER_PARAMS
1515

1616
# Anatomy types accepted by --anatomy-type, sourced from the renderer's
1717
# registered defaults so that new groups/organs registered in
@@ -193,7 +193,7 @@ def main() -> int:
193193
return 1
194194

195195
try:
196-
from physiomotion4d import WorkflowConvertVTKToUSD
196+
from .. import WorkflowConvertVTKToUSD
197197

198198
workflow = WorkflowConvertVTKToUSD(
199199
vtk_files=args.vtk_files,

src/physiomotion4d/cli/create_statistical_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def main() -> int:
138138
# Run workflow
139139
print("\nInitializing create statistical model workflow...")
140140
try:
141-
from physiomotion4d import WorkflowCreateStatisticalModel
141+
from .. import WorkflowCreateStatisticalModel
142142

143143
workflow = WorkflowCreateStatisticalModel(
144144
sample_meshes=sample_meshes,

src/physiomotion4d/cli/download_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pathlib import Path
99
from typing import Optional
1010

11-
from physiomotion4d.data_download_tools import DataDownloadTools
11+
from ..data_download_tools import DataDownloadTools
1212

1313
SLICER_HEART_CT = "Slicer-Heart-CT"
1414

0 commit comments

Comments
 (0)