From fa1cec8cfc1588582d495250b6363a7175329452 Mon Sep 17 00:00:00 2001 From: Stephen Aylward Date: Mon, 6 Jul 2026 22:15:50 -0400 Subject: [PATCH 1/2] Rename physiomotion4d package to physiotwin4d Move src/physiomotion4d -> src/physiotwin4d and physiomotion4d_base.py -> physiotwin4d_base.py, rename PhysioMotion4DBase -> PhysioTwin4DBase, and update all imports, the shared logger name, pyproject.toml packaging metadata (name, console scripts, project URLs, mypy/coverage/ruff config), and tutorials/tests import statements accordingly. Co-Authored-By: Claude Sonnet 5 --- .pre-commit-config.yaml | 4 +- pyproject.toml | 52 +++++++++--------- .../.gitignore | 0 .../__init__.py | 10 ++-- .../anatomy_taxonomy.py | 8 +-- .../cli/__init__.py | 2 +- .../cli/_method_factories.py | 2 +- .../cli/convert_image_4d_to_3d.py | 0 .../cli/convert_image_to_usd.py | 0 .../cli/convert_image_to_vtk.py | 0 .../cli/convert_vtk_to_usd.py | 0 .../cli/create_statistical_model.py | 0 .../cli/download_data.py | 6 +-- .../cli/fit_statistical_model_to_patient.py | 0 .../cli/reconstruct_highres_4d_ct.py | 0 .../cli/visualize_pca_modes.py | 0 .../contour_tools.py | 4 +- .../convert_image_4d_to_3d.py | 4 +- .../convert_vtk_to_usd.py | 4 +- .../data_download_tools.py | 2 +- .../image_tools.py | 6 +-- .../labelmap_tools.py | 6 +-- .../landmark_tools.py | 4 +- .../physiotwin4d_base.py} | 54 +++++++++---------- .../register_images_ants.py | 0 .../register_images_base.py | 4 +- .../register_images_chain.py | 0 .../register_images_greedy.py | 0 .../register_images_greedy_icon.py | 0 .../register_images_icon.py | 0 .../register_models_distance_maps.py | 6 +-- .../register_models_icp.py | 6 +-- .../register_models_icp_itk.py | 4 +- .../register_models_pca.py | 6 +-- .../register_time_series_images.py | 0 .../segment_anatomy_base.py | 10 ++-- .../segment_chest_total_segmentator.py | 0 ...t_chest_total_segmentator_with_contrast.py | 0 .../segment_heart_simpleware.py | 0 ...gment_heart_simpleware_trimmed_branches.py | 0 .../simpleware_medical/README.md | 14 ++--- .../SimplewareScript_heart_segmentation.py | 2 +- .../simpleware_medical/__init__.py | 4 +- .../test_tools.py | 12 ++--- .../transform_tools.py | 4 +- .../usd_anatomy_tools.py | 10 ++-- .../usd_tools.py | 4 +- .../vtk_to_usd/CLAUDE.md | 8 +-- .../vtk_to_usd/README.md | 12 ++--- .../vtk_to_usd/__init__.py | 6 +-- .../vtk_to_usd/converter.py | 2 +- .../vtk_to_usd/data_structures.py | 0 .../vtk_to_usd/material_manager.py | 0 .../vtk_to_usd/mesh_utils.py | 0 .../vtk_to_usd/primvar_derivations.py | 0 .../vtk_to_usd/usd_mesh_converter.py | 0 .../vtk_to_usd/usd_utils.py | 2 +- .../vtk_to_usd/vtk_reader.py | 0 .../workflow_convert_image_to_usd.py | 6 +-- .../workflow_convert_image_to_vtk.py | 8 +-- .../workflow_convert_vtk_to_usd.py | 4 +- .../workflow_create_statistical_model.py | 4 +- .../workflow_fine_tune_icon_registration.py | 6 +-- ...rkflow_fit_statistical_model_to_patient.py | 4 +- .../workflow_reconstruct_highres_4d_ct.py | 4 +- tests/README.md | 8 +-- tests/__init__.py | 4 +- tests/conftest.py | 24 ++++----- tests/test_anatomy_taxonomy.py | 6 +-- tests/test_cli_smoke.py | 26 ++++----- tests/test_contour_tools.py | 2 +- tests/test_convert_image_4d_to_3d.py | 2 +- tests/test_convert_vtk_to_usd.py | 6 +-- tests/test_download_data_cli.py | 4 +- tests/test_download_heart_data.py | 2 +- tests/test_experiments.py | 2 +- tests/test_image_tools.py | 4 +- tests/test_import_public_api.py | 8 +-- tests/test_labelmap_tools.py | 2 +- tests/test_register_images_ants.py | 6 +-- tests/test_register_images_chain.py | 4 +- tests/test_register_images_greedy.py | 4 +- tests/test_register_images_greedy_icon.py | 8 +-- tests/test_register_images_icon.py | 4 +- tests/test_register_models_pca.py | 2 +- tests/test_register_time_series_images.py | 2 +- tests/test_segment_chest_total_segmentator.py | 4 +- tests/test_segment_heart_simpleware.py | 2 +- ...gment_heart_simpleware_trimmed_branches.py | 4 +- tests/test_transform_tools.py | 4 +- tests/test_tutorials.py | 10 ++-- tests/test_usd_merge.py | 2 +- tests/test_usd_time_preservation.py | 2 +- tests/test_vtk_to_usd_library.py | 8 +-- tests/test_workflow_convert_image_to_usd.py | 8 +-- tests/test_workflow_convert_image_to_vtk.py | 6 +-- ...st_workflow_fine_tune_icon_registration.py | 2 +- ...rkflow_fit_statistical_model_to_patient.py | 10 ++-- ...test_workflow_reconstruct_highres_4d_ct.py | 8 +-- tutorials/README.md | 10 ++-- .../tutorial_01_heart_gated_ct_to_usd.py | 6 +-- tutorials/tutorial_02_ct_to_vtk.py | 8 +-- .../tutorial_03_create_statistical_model.py | 4 +- ...ial_04_fit_statistical_model_to_patient.py | 4 +- tutorials/tutorial_05_vtk_to_usd.py | 4 +- .../tutorial_06_reconstruct_highres_4d_ct.py | 6 +-- tutorials/tutorial_08_cardiac_fit_model.py | 29 +++++----- ...orial_09a_cardiac_train_physicsnemo_mgn.py | 12 ++--- ...orial_09b_cardiac_train_physicsnemo_mlp.py | 16 +++--- ...torial_10a_cardiac_eval_physicsnemo_mgn.py | 6 +-- ...torial_10b_cardiac_eval_physicsnemo_mlp.py | 6 +-- 111 files changed, 314 insertions(+), 317 deletions(-) rename src/{physiomotion4d => physiotwin4d}/.gitignore (100%) rename src/{physiomotion4d => physiotwin4d}/__init__.py (93%) rename src/{physiomotion4d => physiotwin4d}/anatomy_taxonomy.py (95%) rename src/{physiomotion4d => physiotwin4d}/cli/__init__.py (79%) rename src/{physiomotion4d => physiotwin4d}/cli/_method_factories.py (99%) rename src/{physiomotion4d => physiotwin4d}/cli/convert_image_4d_to_3d.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/convert_image_to_usd.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/convert_image_to_vtk.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/convert_vtk_to_usd.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/create_statistical_model.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/download_data.py (86%) rename src/{physiomotion4d => physiotwin4d}/cli/fit_statistical_model_to_patient.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/reconstruct_highres_4d_ct.py (100%) rename src/{physiomotion4d => physiotwin4d}/cli/visualize_pca_modes.py (100%) rename src/{physiomotion4d => physiotwin4d}/contour_tools.py (99%) rename src/{physiomotion4d => physiotwin4d}/convert_image_4d_to_3d.py (99%) rename src/{physiomotion4d => physiotwin4d}/convert_vtk_to_usd.py (99%) rename src/{physiomotion4d => physiotwin4d}/data_download_tools.py (98%) rename src/{physiomotion4d => physiotwin4d}/image_tools.py (99%) rename src/{physiomotion4d => physiotwin4d}/labelmap_tools.py (98%) rename src/{physiomotion4d => physiotwin4d}/landmark_tools.py (98%) rename src/{physiomotion4d/physiomotion4d_base.py => physiotwin4d/physiotwin4d_base.py} (89%) rename src/{physiomotion4d => physiotwin4d}/register_images_ants.py (100%) rename src/{physiomotion4d => physiotwin4d}/register_images_base.py (99%) rename src/{physiomotion4d => physiotwin4d}/register_images_chain.py (100%) rename src/{physiomotion4d => physiotwin4d}/register_images_greedy.py (100%) rename src/{physiomotion4d => physiotwin4d}/register_images_greedy_icon.py (100%) rename src/{physiomotion4d => physiotwin4d}/register_images_icon.py (100%) rename src/{physiomotion4d => physiotwin4d}/register_models_distance_maps.py (99%) rename src/{physiomotion4d => physiotwin4d}/register_models_icp.py (98%) rename src/{physiomotion4d => physiotwin4d}/register_models_icp_itk.py (99%) rename src/{physiomotion4d => physiotwin4d}/register_models_pca.py (99%) rename src/{physiomotion4d => physiotwin4d}/register_time_series_images.py (100%) rename src/{physiomotion4d => physiotwin4d}/segment_anatomy_base.py (98%) rename src/{physiomotion4d => physiotwin4d}/segment_chest_total_segmentator.py (100%) rename src/{physiomotion4d => physiotwin4d}/segment_chest_total_segmentator_with_contrast.py (100%) rename src/{physiomotion4d => physiotwin4d}/segment_heart_simpleware.py (100%) rename src/{physiomotion4d => physiotwin4d}/segment_heart_simpleware_trimmed_branches.py (100%) rename src/{physiomotion4d => physiotwin4d}/simpleware_medical/README.md (91%) rename src/{physiomotion4d => physiotwin4d}/simpleware_medical/SimplewareScript_heart_segmentation.py (95%) rename src/{physiomotion4d => physiotwin4d}/simpleware_medical/__init__.py (61%) rename src/{physiomotion4d => physiotwin4d}/test_tools.py (98%) rename src/{physiomotion4d => physiotwin4d}/transform_tools.py (99%) rename src/{physiomotion4d => physiotwin4d}/usd_anatomy_tools.py (98%) rename src/{physiomotion4d => physiotwin4d}/usd_tools.py (99%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/CLAUDE.md (86%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/README.md (91%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/__init__.py (89%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/converter.py (97%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/data_structures.py (100%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/material_manager.py (100%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/mesh_utils.py (100%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/primvar_derivations.py (100%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/usd_mesh_converter.py (100%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/usd_utils.py (99%) rename src/{physiomotion4d => physiotwin4d}/vtk_to_usd/vtk_reader.py (100%) rename src/{physiomotion4d => physiotwin4d}/workflow_convert_image_to_usd.py (99%) rename src/{physiomotion4d => physiotwin4d}/workflow_convert_image_to_vtk.py (98%) rename src/{physiomotion4d => physiotwin4d}/workflow_convert_vtk_to_usd.py (99%) rename src/{physiomotion4d => physiotwin4d}/workflow_create_statistical_model.py (99%) rename src/{physiomotion4d => physiotwin4d}/workflow_fine_tune_icon_registration.py (99%) rename src/{physiomotion4d => physiotwin4d}/workflow_fit_statistical_model_to_patient.py (99%) rename src/{physiomotion4d => physiotwin4d}/workflow_reconstruct_highres_4d_ct.py (99%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 214e591..c415b09 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -# Pre-commit configuration for PhysioMotion4D +# Pre-commit configuration for PhysioTwin4D # Simplified to use Ruff for all linting and formatting repos: @@ -46,5 +46,5 @@ repos: language: system pass_filenames: false always_run: false - files: ^(src/physiomotion4d/|tests/) + files: ^(src/physiotwin4d/|tests/) stages: [pre-push] diff --git a/pyproject.toml b/pyproject.toml index 3b73d9e..8e2907d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "physiomotion4d" +name = "physiotwin4d" version = "2026.07.0" description = "Medical imaging package for generating anatomic models in Omniverse with physiological motion from 4D medical images" authors = [ @@ -112,7 +112,7 @@ cuda13 = [ ] # PhysicsNeMo pulls in a large dependency stack (CUDA-only toolchain, narrower # Python support). It is only needed for Tutorial 9 (mesh stage MLP). Install -# with ``pip install physiomotion4d[physicsnemo]`` when you need it. Note: +# with ``pip install physiotwin4d[physicsnemo]`` when you need it. Note: # nvidia-physicsnemo itself requires Python >= 3.11. physicsnemo = [ "nvidia-physicsnemo>=2.0.0", @@ -157,25 +157,25 @@ test = [ ] [project.urls] -Homepage = "https://github.com/Project-MONAI/physiomotion4d" -Documentation = "https://project-monai.github.io/physiomotion4d/" -Repository = "https://github.com/Project-MONAI/physiomotion4d.git" -"Bug Tracker" = "https://github.com/Project-MONAI/physiomotion4d/issues" +Homepage = "https://github.com/Project-MONAI/physiotwin4d" +Documentation = "https://project-monai.github.io/physiotwin4d/" +Repository = "https://github.com/Project-MONAI/physiotwin4d.git" +"Bug Tracker" = "https://github.com/Project-MONAI/physiotwin4d/issues" "Author LinkedIn" = "https://www.linkedin.com/in/stephenaylward" "Author Google Scholar" = "https://scholar.google.com/citations?user=u1UdL4oAAAAJ&hl" [project.scripts] # CLI commands installed via pip # Entry points reference the main() functions in the cli submodule -physiomotion4d-convert-image-to-vtk = "physiomotion4d.cli.convert_image_to_vtk:main" -physiomotion4d-convert-image-4d-to-3d = "physiomotion4d.cli.convert_image_4d_to_3d:main" -physiomotion4d-convert-image-to-usd = "physiomotion4d.cli.convert_image_to_usd:main" -physiomotion4d-convert-vtk-to-usd = "physiomotion4d.cli.convert_vtk_to_usd:main" -physiomotion4d-create-statistical-model = "physiomotion4d.cli.create_statistical_model:main" -physiomotion4d-download-data = "physiomotion4d.cli.download_data:main" -physiomotion4d-fit-statistical-model-to-patient = "physiomotion4d.cli.fit_statistical_model_to_patient:main" -physiomotion4d-reconstruct-highres-4d-ct = "physiomotion4d.cli.reconstruct_highres_4d_ct:main" -physiomotion4d-visualize-pca-modes = "physiomotion4d.cli.visualize_pca_modes:main" +physiotwin4d-convert-image-to-vtk = "physiotwin4d.cli.convert_image_to_vtk:main" +physiotwin4d-convert-image-4d-to-3d = "physiotwin4d.cli.convert_image_4d_to_3d:main" +physiotwin4d-convert-image-to-usd = "physiotwin4d.cli.convert_image_to_usd:main" +physiotwin4d-convert-vtk-to-usd = "physiotwin4d.cli.convert_vtk_to_usd:main" +physiotwin4d-create-statistical-model = "physiotwin4d.cli.create_statistical_model:main" +physiotwin4d-download-data = "physiotwin4d.cli.download_data:main" +physiotwin4d-fit-statistical-model-to-patient = "physiotwin4d.cli.fit_statistical_model_to_patient:main" +physiotwin4d-reconstruct-highres-4d-ct = "physiotwin4d.cli.reconstruct_highres_4d_ct:main" +physiotwin4d-visualize-pca-modes = "physiotwin4d.cli.visualize_pca_modes:main" [tool.setuptools.packages.find] where = ["src"] @@ -194,7 +194,7 @@ push = false 'current_version = "{version}"', 'version = "{version}"', ] -"src/physiomotion4d/__init__.py" = [ +"src/physiotwin4d/__init__.py" = [ '__version__ = "{version}"', ] @@ -265,11 +265,11 @@ ignore_missing_imports = true [[tool.mypy.overrides]] module = [ - "physiomotion4d.cli.create_statistical_model", - "physiomotion4d.cli.fit_statistical_model_to_patient", - "physiomotion4d.cli.visualize_pca_modes", - "physiomotion4d.vtk_to_usd.mesh_utils", - "physiomotion4d.vtk_to_usd.vtk_reader", + "physiotwin4d.cli.create_statistical_model", + "physiotwin4d.cli.fit_statistical_model_to_patient", + "physiotwin4d.cli.visualize_pca_modes", + "physiotwin4d.vtk_to_usd.mesh_utils", + "physiotwin4d.vtk_to_usd.vtk_reader", "tutorial_08_cardiac_fit_model", "tutorial_09a_cardiac_train_physicsnemo_mgn", "tutorial_09b_cardiac_train_physicsnemo_mlp", @@ -281,7 +281,7 @@ disable_error_code = ["import-not-found", "import-untyped"] [[tool.mypy.overrides]] # torch/icon_registration/unigradicon are lazy-loaded at runtime; string # forward-reference annotations like "torch.Size" are intentional. -module = ["physiomotion4d.register_images_icon"] +module = ["physiotwin4d.register_images_icon"] ignore_errors = true [tool.pyright] @@ -294,7 +294,7 @@ minversion = "7.0" addopts = [ "--strict-markers", "--strict-config", - "--cov=physiomotion4d", + "--cov=physiotwin4d", "--cov-report=term-missing", "--cov-report=html", "--cov-report=xml" @@ -326,7 +326,7 @@ markers = [ timeout = 1200 [tool.coverage.run] -source = ["src/physiomotion4d"] +source = ["src/physiotwin4d"] omit = [ "*/tests/*", "*/test_*", @@ -413,10 +413,10 @@ ignore = [ "tests/*.py" = ["S101", "PLR2004", "ARG001", "ARG002"] "experiments/**/*.py" = ["T201", "S101"] # torch/icon_registration are lazy-loaded at runtime; forward-reference strings are intentional -"src/physiomotion4d/register_images_icon.py" = ["F821"] +"src/physiotwin4d/register_images_icon.py" = ["F821"] [tool.ruff.lint.isort] -known-first-party = ["physiomotion4d"] +known-first-party = ["physiotwin4d"] force-single-line = false lines-after-imports = 2 diff --git a/src/physiomotion4d/.gitignore b/src/physiotwin4d/.gitignore similarity index 100% rename from src/physiomotion4d/.gitignore rename to src/physiotwin4d/.gitignore diff --git a/src/physiomotion4d/__init__.py b/src/physiotwin4d/__init__.py similarity index 93% rename from src/physiomotion4d/__init__.py rename to src/physiotwin4d/__init__.py index 73cdd5e..c165699 100644 --- a/src/physiomotion4d/__init__.py +++ b/src/physiotwin4d/__init__.py @@ -1,5 +1,5 @@ """ -PhysioMotion4D - Medical imaging package for generating anatomic models with +PhysioTwin4D - Medical imaging package for generating anatomic models with physiological motion. This package converts 4D CT scans (particularly heart and lung gated CT data) into @@ -14,7 +14,7 @@ - Registration tools: Deep learning-based image registration - Transform utilities: Tools for image and contour transformations - USD tools: Utilities for Omniverse integration - - PhysioMotion4DBase: Base class with standardized logging and debug settings + - PhysioTwin4DBase: Base class with standardized logging and debug settings """ __version__ = "2026.07.0" @@ -27,7 +27,7 @@ "CuPy is not installed — GPU acceleration is unavailable and processing " "will be slow. Re-install with uv to get CuPy and CUDA-enabled PyTorch " "in one step (pip alone will not select the correct CUDA wheel):\n" - " uv pip install 'physiomotion4d[cuda13]' # CUDA 13", + " uv pip install 'physiotwin4d[cuda13]' # CUDA 13", UserWarning, stacklevel=2, ) @@ -46,7 +46,7 @@ from .landmark_tools import LandmarkTools # Base classes -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_ants import RegisterImagesANTS from .register_images_greedy import RegisterImagesGreedy @@ -115,7 +115,7 @@ "RegisterModelsICPITK", "RegisterModelsDistanceMaps", # Base classes - "PhysioMotion4DBase", + "PhysioTwin4DBase", # Utility classes "ImageTools", "LabelmapTools", diff --git a/src/physiomotion4d/anatomy_taxonomy.py b/src/physiotwin4d/anatomy_taxonomy.py similarity index 95% rename from src/physiomotion4d/anatomy_taxonomy.py rename to src/physiotwin4d/anatomy_taxonomy.py index 55b1c9c..0ab9a5d 100644 --- a/src/physiomotion4d/anatomy_taxonomy.py +++ b/src/physiotwin4d/anatomy_taxonomy.py @@ -5,8 +5,8 @@ ...) to the organ labels they contain. The taxonomy is the single source of truth for the label hierarchy. Both -:class:`physiomotion4d.SegmentAnatomyBase` (which populates one via its -subclasses) and :class:`physiomotion4d.USDAnatomyTools` (which consumes one +:class:`physiotwin4d.SegmentAnatomyBase` (which populates one via its +subclasses) and :class:`physiotwin4d.USDAnatomyTools` (which consumes one when applying materials) depend on this class. The two consumers do not depend on each other, which lets either side be used without the other. @@ -121,7 +121,7 @@ def group_for_label(self, label_name: str) -> str: """Return the group containing *label_name*. Falls back to :data:`OTHER_GROUP` if no group contains the name; this - keeps :class:`physiomotion4d.ConvertVTKToUSD` happy when it encounters + keeps :class:`physiotwin4d.ConvertVTKToUSD` happy when it encounters labels the segmenter did not classify. """ for anatomy_group in self._groups.values(): @@ -143,7 +143,7 @@ def fill_other_group( ) -> None: """Populate the ``other`` group with any ids not already claimed. - Called by :class:`physiomotion4d.SegmentAnatomyBase` subclasses at the + Called by :class:`physiotwin4d.SegmentAnatomyBase` subclasses at the end of ``__init__`` to mark every id in the segmenter's class index space that no specific group claimed. diff --git a/src/physiomotion4d/cli/__init__.py b/src/physiotwin4d/cli/__init__.py similarity index 79% rename from src/physiomotion4d/cli/__init__.py rename to src/physiotwin4d/cli/__init__.py index d498484..35f1794 100644 --- a/src/physiomotion4d/cli/__init__.py +++ b/src/physiotwin4d/cli/__init__.py @@ -1,4 +1,4 @@ -"""Command-line interface modules for PhysioMotion4D.""" +"""Command-line interface modules for PhysioTwin4D.""" __all__ = [ "convert_image_to_usd", diff --git a/src/physiomotion4d/cli/_method_factories.py b/src/physiotwin4d/cli/_method_factories.py similarity index 99% rename from src/physiomotion4d/cli/_method_factories.py rename to src/physiotwin4d/cli/_method_factories.py index eb4191d..316655c 100644 --- a/src/physiomotion4d/cli/_method_factories.py +++ b/src/physiotwin4d/cli/_method_factories.py @@ -5,7 +5,7 @@ passing it to the library's instance-based workflow API. """ -from physiomotion4d import ( +from physiotwin4d import ( RegisterImagesBase, RegisterImagesGreedy, RegisterImagesGreedyICON, diff --git a/src/physiomotion4d/cli/convert_image_4d_to_3d.py b/src/physiotwin4d/cli/convert_image_4d_to_3d.py similarity index 100% rename from src/physiomotion4d/cli/convert_image_4d_to_3d.py rename to src/physiotwin4d/cli/convert_image_4d_to_3d.py diff --git a/src/physiomotion4d/cli/convert_image_to_usd.py b/src/physiotwin4d/cli/convert_image_to_usd.py similarity index 100% rename from src/physiomotion4d/cli/convert_image_to_usd.py rename to src/physiotwin4d/cli/convert_image_to_usd.py diff --git a/src/physiomotion4d/cli/convert_image_to_vtk.py b/src/physiotwin4d/cli/convert_image_to_vtk.py similarity index 100% rename from src/physiomotion4d/cli/convert_image_to_vtk.py rename to src/physiotwin4d/cli/convert_image_to_vtk.py diff --git a/src/physiomotion4d/cli/convert_vtk_to_usd.py b/src/physiotwin4d/cli/convert_vtk_to_usd.py similarity index 100% rename from src/physiomotion4d/cli/convert_vtk_to_usd.py rename to src/physiotwin4d/cli/convert_vtk_to_usd.py diff --git a/src/physiomotion4d/cli/create_statistical_model.py b/src/physiotwin4d/cli/create_statistical_model.py similarity index 100% rename from src/physiomotion4d/cli/create_statistical_model.py rename to src/physiotwin4d/cli/create_statistical_model.py diff --git a/src/physiomotion4d/cli/download_data.py b/src/physiotwin4d/cli/download_data.py similarity index 86% rename from src/physiomotion4d/cli/download_data.py rename to src/physiotwin4d/cli/download_data.py index 22dd169..952c82f 100644 --- a/src/physiomotion4d/cli/download_data.py +++ b/src/physiotwin4d/cli/download_data.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -"""Command-line interface for downloading PhysioMotion4D example data.""" +"""Command-line interface for downloading PhysioTwin4D example data.""" from __future__ import annotations @@ -14,9 +14,9 @@ def main(argv: Optional[list[str]] = None) -> int: - """Download a supported PhysioMotion4D example dataset.""" + """Download a supported PhysioTwin4D example dataset.""" parser = argparse.ArgumentParser( - description="Download PhysioMotion4D example data", + description="Download PhysioTwin4D example data", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=f""" Examples: diff --git a/src/physiomotion4d/cli/fit_statistical_model_to_patient.py b/src/physiotwin4d/cli/fit_statistical_model_to_patient.py similarity index 100% rename from src/physiomotion4d/cli/fit_statistical_model_to_patient.py rename to src/physiotwin4d/cli/fit_statistical_model_to_patient.py diff --git a/src/physiomotion4d/cli/reconstruct_highres_4d_ct.py b/src/physiotwin4d/cli/reconstruct_highres_4d_ct.py similarity index 100% rename from src/physiomotion4d/cli/reconstruct_highres_4d_ct.py rename to src/physiotwin4d/cli/reconstruct_highres_4d_ct.py diff --git a/src/physiomotion4d/cli/visualize_pca_modes.py b/src/physiotwin4d/cli/visualize_pca_modes.py similarity index 100% rename from src/physiomotion4d/cli/visualize_pca_modes.py rename to src/physiotwin4d/cli/visualize_pca_modes.py diff --git a/src/physiomotion4d/contour_tools.py b/src/physiotwin4d/contour_tools.py similarity index 99% rename from src/physiomotion4d/contour_tools.py rename to src/physiotwin4d/contour_tools.py index cd8219d..533e7e9 100644 --- a/src/physiomotion4d/contour_tools.py +++ b/src/physiotwin4d/contour_tools.py @@ -14,11 +14,11 @@ import trimesh from .image_tools import ImageTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .transform_tools import TransformTools -class ContourTools(PhysioMotion4DBase): +class ContourTools(PhysioTwin4DBase): """ Tools for creating and manipulating contours. """ diff --git a/src/physiomotion4d/convert_image_4d_to_3d.py b/src/physiotwin4d/convert_image_4d_to_3d.py similarity index 99% rename from src/physiomotion4d/convert_image_4d_to_3d.py rename to src/physiotwin4d/convert_image_4d_to_3d.py index 17f1e8a..0608b0f 100644 --- a/src/physiomotion4d/convert_image_4d_to_3d.py +++ b/src/physiotwin4d/convert_image_4d_to_3d.py @@ -28,10 +28,10 @@ import numpy as np import pydicom -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase -class ConvertImage4DTo3D(PhysioMotion4DBase): +class ConvertImage4DTo3D(PhysioTwin4DBase): """Split a 3D/4D ITK image into a list of 3D ITK images.""" def __init__(self, log_level: int | str = logging.INFO) -> None: diff --git a/src/physiomotion4d/convert_vtk_to_usd.py b/src/physiotwin4d/convert_vtk_to_usd.py similarity index 99% rename from src/physiomotion4d/convert_vtk_to_usd.py rename to src/physiotwin4d/convert_vtk_to_usd.py index 8c1b821..d6f0bc9 100644 --- a/src/physiomotion4d/convert_vtk_to_usd.py +++ b/src/physiotwin4d/convert_vtk_to_usd.py @@ -23,7 +23,7 @@ import vtk from pxr import Sdf, Usd, UsdGeom -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .segment_anatomy_base import SegmentAnatomyBase from .vtk_to_usd import ( ConversionSettings, @@ -42,7 +42,7 @@ ) -class ConvertVTKToUSD(PhysioMotion4DBase): +class ConvertVTKToUSD(PhysioTwin4DBase): """ Advanced VTK to USD converter with colormap and anatomical labeling support. diff --git a/src/physiomotion4d/data_download_tools.py b/src/physiotwin4d/data_download_tools.py similarity index 98% rename from src/physiomotion4d/data_download_tools.py rename to src/physiotwin4d/data_download_tools.py index 9af2a03..07f5cb0 100644 --- a/src/physiomotion4d/data_download_tools.py +++ b/src/physiotwin4d/data_download_tools.py @@ -18,7 +18,7 @@ class DataDownloadTools: - """Download and verify optional PhysioMotion4D example datasets.""" + """Download and verify optional PhysioTwin4D example datasets.""" SLICER_HEART_CT_URL = ( "https://github.com/SlicerHeart/SlicerHeart/releases/download/" diff --git a/src/physiomotion4d/image_tools.py b/src/physiotwin4d/image_tools.py similarity index 99% rename from src/physiomotion4d/image_tools.py rename to src/physiotwin4d/image_tools.py index 03dd41a..0e5c4e2 100644 --- a/src/physiomotion4d/image_tools.py +++ b/src/physiotwin4d/image_tools.py @@ -1,5 +1,5 @@ """ -Image Tools for PhysioMotion4D +Image Tools for PhysioTwin4D This module provides utilities for converting between different medical image formats and performing image processing operations. @@ -13,10 +13,10 @@ import SimpleITK as sitk from numpy.typing import NDArray -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase -class ImageTools(PhysioMotion4DBase): +class ImageTools(PhysioTwin4DBase): """ Utilities for medical image format conversions and processing. diff --git a/src/physiomotion4d/labelmap_tools.py b/src/physiotwin4d/labelmap_tools.py similarity index 98% rename from src/physiomotion4d/labelmap_tools.py rename to src/physiotwin4d/labelmap_tools.py index 737b7b4..bf89fab 100644 --- a/src/physiomotion4d/labelmap_tools.py +++ b/src/physiotwin4d/labelmap_tools.py @@ -1,5 +1,5 @@ """ -Labelmap Tools for PhysioMotion4D +Labelmap Tools for PhysioTwin4D This module provides the :class:`LabelmapTools` class with the definitive utility for turning a multi-label (or binary) segmentation labelmap into a @@ -13,10 +13,10 @@ import itk import numpy as np -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase -class LabelmapTools(PhysioMotion4DBase): +class LabelmapTools(PhysioTwin4DBase): """ Utilities for converting segmentation labelmaps into registration masks. diff --git a/src/physiomotion4d/landmark_tools.py b/src/physiotwin4d/landmark_tools.py similarity index 98% rename from src/physiomotion4d/landmark_tools.py rename to src/physiotwin4d/landmark_tools.py index 9249cfd..a76b060 100644 --- a/src/physiomotion4d/landmark_tools.py +++ b/src/physiotwin4d/landmark_tools.py @@ -14,7 +14,7 @@ import logging from pathlib import Path -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase LandmarkDict = dict[str, tuple[float, float, float]] @@ -25,7 +25,7 @@ ) -class LandmarkTools(PhysioMotion4DBase): +class LandmarkTools(PhysioTwin4DBase): """ Read and write anatomical landmarks in LPS world coordinates. diff --git a/src/physiomotion4d/physiomotion4d_base.py b/src/physiotwin4d/physiotwin4d_base.py similarity index 89% rename from src/physiomotion4d/physiomotion4d_base.py rename to src/physiotwin4d/physiotwin4d_base.py index 336a111..cda5a8a 100644 --- a/src/physiomotion4d/physiomotion4d_base.py +++ b/src/physiotwin4d/physiotwin4d_base.py @@ -1,17 +1,17 @@ -"""Base class for PhysioMotion4D providing standardized logging and debug settings. +"""Base class for PhysioTwin4D providing standardized logging and debug settings. -This module provides the PhysioMotion4DBase class that can be inherited by other -classes in the PhysioMotion4D package to provide consistent logging and messaging +This module provides the PhysioTwin4DBase class that can be inherited by other +classes in the PhysioTwin4D package to provide consistent logging and messaging functionality instead of scattered print statements. -All classes share a common logger called "PhysioMotion4D" but include their class +All classes share a common logger called "PhysioTwin4D" but include their class name in log messages for identification. Users can filter which classes show logs. Example: - >>> from physiomotion4d.physiomotion4d_base import PhysioMotion4DBase + >>> from physiotwin4d.physiotwin4d_base import PhysioTwin4DBase >>> import logging >>> - >>> class MyClass(PhysioMotion4DBase): + >>> class MyClass(PhysioTwin4DBase): ... def __init__(self): ... super().__init__(class_name='MyClass', log_level=logging.INFO) ... @@ -24,10 +24,10 @@ >>> obj.process() >>> >>> # Filter to show only specific classes - >>> PhysioMotion4DBase.set_log_classes(['MyClass', 'OtherClass']) + >>> PhysioTwin4DBase.set_log_classes(['MyClass', 'OtherClass']) >>> >>> # Show all classes again - >>> PhysioMotion4DBase.set_log_all_classes() + >>> PhysioTwin4DBase.set_log_all_classes() """ import logging @@ -65,15 +65,15 @@ def filter(self, record: logging.LogRecord) -> bool: return True # Show messages without class name attribute -class PhysioMotion4DBase: +class PhysioTwin4DBase: """Base class providing standardized logging and debug settings. - This class provides a consistent logging interface for all PhysioMotion4D - classes. All classes share a common logger called "PhysioMotion4D" but include + This class provides a consistent logging interface for all PhysioTwin4D + classes. All classes share a common logger called "PhysioTwin4D" but include their class name in log messages for identification. Class Attributes: - _shared_logger (logging.Logger): Shared logger for all PhysioMotion4D classes + _shared_logger (logging.Logger): Shared logger for all PhysioTwin4D classes _class_filter (ClassNameFilter): Filter for controlling which classes show logs _logger_initialized (bool): Whether the shared logger has been set up @@ -83,7 +83,7 @@ class PhysioMotion4DBase: Example: >>> import logging - >>> class MyRegistration(PhysioMotion4DBase): + >>> class MyRegistration(PhysioTwin4DBase): ... def __init__(self): ... super().__init__(class_name='MyRegistration', log_level=logging.INFO) ... @@ -92,10 +92,10 @@ class PhysioMotion4DBase: ... self.log_debug('Using parameters: ...') >>> >>> # Filter to show only specific classes - >>> PhysioMotion4DBase.set_log_classes(['MyRegistration']) + >>> PhysioTwin4DBase.set_log_classes(['MyRegistration']) >>> >>> # Show all classes again - >>> PhysioMotion4DBase.set_log_all_classes() + >>> PhysioTwin4DBase.set_log_all_classes() """ # Class-level shared logger and filter @@ -127,12 +127,12 @@ def __init__( self.class_name = class_name # Initialize shared logger if not already done - if not PhysioMotion4DBase._logger_initialized: - PhysioMotion4DBase._initialize_shared_logger(log_level, log_to_file) + if not PhysioTwin4DBase._logger_initialized: + PhysioTwin4DBase._initialize_shared_logger(log_level, log_to_file) # Get reference to shared logger - assert PhysioMotion4DBase._shared_logger is not None - self.logger: logging.Logger = PhysioMotion4DBase._shared_logger + assert PhysioTwin4DBase._shared_logger is not None + self.logger: logging.Logger = PhysioTwin4DBase._shared_logger # Store the log level if isinstance(log_level, str): @@ -150,7 +150,7 @@ def _initialize_shared_logger( return # Create the shared logger - cls._shared_logger = logging.getLogger("PhysioMotion4D") + cls._shared_logger = logging.getLogger("PhysioTwin4D") # Convert string log level to integer if needed if isinstance(log_level, str): @@ -195,7 +195,7 @@ def _initialize_shared_logger( @classmethod def set_log_level(cls, log_level: int | str) -> None: - """Set the logging level for all PhysioMotion4D classes. + """Set the logging level for all PhysioTwin4D classes. Args: log_level: Logging level. Can be an integer (logging.DEBUG, logging.INFO, @@ -204,9 +204,9 @@ def set_log_level(cls, log_level: int | str) -> None: Example: >>> import logging - >>> PhysioMotion4DBase.set_log_level(logging.DEBUG) + >>> PhysioTwin4DBase.set_log_level(logging.DEBUG) >>> # or - >>> PhysioMotion4DBase.set_log_level('DEBUG') + >>> PhysioTwin4DBase.set_log_level('DEBUG') """ # Convert string log level to integer if needed if isinstance(log_level, str): @@ -231,7 +231,7 @@ def set_log_classes(cls, class_names: list[str]) -> None: Example: ["RegisterModelsPCA", "WorkflowFitStatisticalModelToPatient"] Example: - >>> PhysioMotion4DBase.set_log_classes(['RegisterModelsPCA']) + >>> PhysioTwin4DBase.set_log_classes(['RegisterModelsPCA']) >>> # Now only RegisterModelsPCA logs will be shown """ if cls._class_filter is not None: @@ -240,12 +240,12 @@ def set_log_classes(cls, class_names: list[str]) -> None: @classmethod def set_log_all_classes(cls) -> None: - """Enable logging output from all PhysioMotion4D classes. + """Enable logging output from all PhysioTwin4D classes. Disables the class filter so all classes show their logs. Example: - >>> PhysioMotion4DBase.set_log_all_classes() + >>> PhysioTwin4DBase.set_log_all_classes() >>> # Now all classes will show their logs """ if cls._class_filter is not None: @@ -261,7 +261,7 @@ def get_log_classes(cls) -> list[str]: Empty list if filter is disabled (all classes shown). Example: - >>> classes = PhysioMotion4DBase.get_log_classes() + >>> classes = PhysioTwin4DBase.get_log_classes() >>> print(classes) ['RegisterModelsPCA', 'WorkflowFitStatisticalModelToPatient'] """ diff --git a/src/physiomotion4d/register_images_ants.py b/src/physiotwin4d/register_images_ants.py similarity index 100% rename from src/physiomotion4d/register_images_ants.py rename to src/physiotwin4d/register_images_ants.py diff --git a/src/physiomotion4d/register_images_base.py b/src/physiotwin4d/register_images_base.py similarity index 99% rename from src/physiomotion4d/register_images_base.py rename to src/physiotwin4d/register_images_base.py index 0f494d2..64e0d7c 100644 --- a/src/physiomotion4d/register_images_base.py +++ b/src/physiotwin4d/register_images_base.py @@ -21,11 +21,11 @@ import itk from .labelmap_tools import LabelmapTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .transform_tools import TransformTools -class RegisterImagesBase(PhysioMotion4DBase): +class RegisterImagesBase(PhysioTwin4DBase): """Base class for deformable image registration algorithms. This class provides a common interface and shared functionality for diff --git a/src/physiomotion4d/register_images_chain.py b/src/physiotwin4d/register_images_chain.py similarity index 100% rename from src/physiomotion4d/register_images_chain.py rename to src/physiotwin4d/register_images_chain.py diff --git a/src/physiomotion4d/register_images_greedy.py b/src/physiotwin4d/register_images_greedy.py similarity index 100% rename from src/physiomotion4d/register_images_greedy.py rename to src/physiotwin4d/register_images_greedy.py diff --git a/src/physiomotion4d/register_images_greedy_icon.py b/src/physiotwin4d/register_images_greedy_icon.py similarity index 100% rename from src/physiomotion4d/register_images_greedy_icon.py rename to src/physiotwin4d/register_images_greedy_icon.py diff --git a/src/physiomotion4d/register_images_icon.py b/src/physiotwin4d/register_images_icon.py similarity index 100% rename from src/physiomotion4d/register_images_icon.py rename to src/physiotwin4d/register_images_icon.py diff --git a/src/physiomotion4d/register_models_distance_maps.py b/src/physiotwin4d/register_models_distance_maps.py similarity index 99% rename from src/physiomotion4d/register_models_distance_maps.py rename to src/physiotwin4d/register_models_distance_maps.py index dc34704..f7d94d8 100644 --- a/src/physiomotion4d/register_models_distance_maps.py +++ b/src/physiotwin4d/register_models_distance_maps.py @@ -21,7 +21,7 @@ Example: >>> import itk >>> import pyvista as pv - >>> from physiomotion4d import RegisterModelsDistanceMaps + >>> from physiotwin4d import RegisterModelsDistanceMaps >>> >>> # Load models and reference image >>> moving_model = pv.read('generic_model.vtu').extract_surface(algorithm="dataset_surface") @@ -50,13 +50,13 @@ from .contour_tools import ContourTools from .labelmap_tools import LabelmapTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_greedy import RegisterImagesGreedy from .register_images_icon import RegisterImagesICON from .transform_tools import TransformTools -class RegisterModelsDistanceMaps(PhysioMotion4DBase): +class RegisterModelsDistanceMaps(PhysioTwin4DBase): """Register anatomical models using distance-map-based deformable registration. This class provides distance-map-based alignment of 3D surface models with support diff --git a/src/physiomotion4d/register_models_icp.py b/src/physiotwin4d/register_models_icp.py similarity index 98% rename from src/physiomotion4d/register_models_icp.py rename to src/physiotwin4d/register_models_icp.py index ce2dc95..c845a65 100644 --- a/src/physiomotion4d/register_models_icp.py +++ b/src/physiotwin4d/register_models_icp.py @@ -17,7 +17,7 @@ Example: >>> import pyvista as pv - >>> from physiomotion4d import RegisterModelsICP + >>> from physiotwin4d import RegisterModelsICP >>> >>> # Load models >>> moving_model = pv.read('generic_model.vtu') @@ -45,11 +45,11 @@ import pyvista as pv import vtk -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .transform_tools import TransformTools -class RegisterModelsICP(PhysioMotion4DBase): +class RegisterModelsICP(PhysioTwin4DBase): """Register anatomical models using Iterative Closest Point (ICP) algorithm. This class provides ICP-based alignment of 3D surface models with support for diff --git a/src/physiomotion4d/register_models_icp_itk.py b/src/physiotwin4d/register_models_icp_itk.py similarity index 99% rename from src/physiomotion4d/register_models_icp_itk.py rename to src/physiotwin4d/register_models_icp_itk.py index 27c7ef7..1bb70c3 100644 --- a/src/physiomotion4d/register_models_icp_itk.py +++ b/src/physiotwin4d/register_models_icp_itk.py @@ -7,11 +7,11 @@ from scipy.optimize import minimize from .contour_tools import ContourTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .transform_tools import TransformTools -class RegisterModelsICPITK(PhysioMotion4DBase): +class RegisterModelsICPITK(PhysioTwin4DBase): """Register shape models using model to distance map minimization. **Optimization Objective:** diff --git a/src/physiomotion4d/register_models_pca.py b/src/physiotwin4d/register_models_pca.py similarity index 99% rename from src/physiomotion4d/register_models_pca.py rename to src/physiotwin4d/register_models_pca.py index 635e825..ef93d97 100644 --- a/src/physiomotion4d/register_models_pca.py +++ b/src/physiotwin4d/register_models_pca.py @@ -12,11 +12,11 @@ from typing_extensions import Self from .contour_tools import ContourTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .transform_tools import TransformTools -class RegisterModelsPCA(PhysioMotion4DBase): +class RegisterModelsPCA(PhysioTwin4DBase): """Register PCA-based shape models to medical images using mean distance optimization. This class implements a registration pipeline for fitting statistical @@ -237,7 +237,7 @@ def from_json( """ # Create a logger for the classmethod since superclass hasn't # been initialized yet. - logger = logging.getLogger("PhysioMotion4D") + logger = logging.getLogger("PhysioTwin4D") json_path = Path(pca_json_filename) diff --git a/src/physiomotion4d/register_time_series_images.py b/src/physiotwin4d/register_time_series_images.py similarity index 100% rename from src/physiomotion4d/register_time_series_images.py rename to src/physiotwin4d/register_time_series_images.py diff --git a/src/physiomotion4d/segment_anatomy_base.py b/src/physiotwin4d/segment_anatomy_base.py similarity index 98% rename from src/physiomotion4d/segment_anatomy_base.py rename to src/physiotwin4d/segment_anatomy_base.py index af40642..c0f6865 100644 --- a/src/physiomotion4d/segment_anatomy_base.py +++ b/src/physiotwin4d/segment_anatomy_base.py @@ -12,10 +12,10 @@ import numpy as np from .anatomy_taxonomy import AnatomyTaxonomy -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase -class SegmentAnatomyBase(PhysioMotion4DBase): +class SegmentAnatomyBase(PhysioTwin4DBase): """Base class for anatomy segmentation that provides common functionality for segmenting anatomy in CT images. @@ -34,7 +34,7 @@ class SegmentAnatomyBase(PhysioMotion4DBase): ``self.taxonomy.add_organ(group_name, label_id, organ_name)`` for each organ; the group is created lazily on first use. To assign a custom OmniSurface look to a new group, register it in - :data:`physiomotion4d.usd_anatomy_tools.DEFAULT_RENDER_PARAMS` (see that + :data:`physiotwin4d.usd_anatomy_tools.DEFAULT_RENDER_PARAMS` (see that module's docstring). Groups without a registered look fall back to the ``"other"`` entry, so they still render. @@ -45,7 +45,7 @@ class SegmentAnatomyBase(PhysioMotion4DBase): passes and use faster/less-accurate models to trade segmentation fidelity for speed (e.g. in automated tests). Defaults to False. taxonomy (AnatomyTaxonomy): Group→organ mapping shared with - :class:`physiomotion4d.USDAnatomyTools`. + :class:`physiotwin4d.USDAnatomyTools`. """ def __init__(self, log_level: int | str = logging.INFO): @@ -84,7 +84,7 @@ def _finalize_other_group(self) -> None: def label_to_type(self, label_name: str) -> str: """Return the anatomy group ('heart', 'lung', etc.) for a label name. - Used by :class:`physiomotion4d.ConvertVTKToUSD` to group label-mode + Used by :class:`physiotwin4d.ConvertVTKToUSD` to group label-mode mesh prims under per-type Xforms (e.g. ``/World/{basename}/heart/{label_name}``). Delegates to the taxonomy. diff --git a/src/physiomotion4d/segment_chest_total_segmentator.py b/src/physiotwin4d/segment_chest_total_segmentator.py similarity index 100% rename from src/physiomotion4d/segment_chest_total_segmentator.py rename to src/physiotwin4d/segment_chest_total_segmentator.py diff --git a/src/physiomotion4d/segment_chest_total_segmentator_with_contrast.py b/src/physiotwin4d/segment_chest_total_segmentator_with_contrast.py similarity index 100% rename from src/physiomotion4d/segment_chest_total_segmentator_with_contrast.py rename to src/physiotwin4d/segment_chest_total_segmentator_with_contrast.py diff --git a/src/physiomotion4d/segment_heart_simpleware.py b/src/physiotwin4d/segment_heart_simpleware.py similarity index 100% rename from src/physiomotion4d/segment_heart_simpleware.py rename to src/physiotwin4d/segment_heart_simpleware.py diff --git a/src/physiomotion4d/segment_heart_simpleware_trimmed_branches.py b/src/physiotwin4d/segment_heart_simpleware_trimmed_branches.py similarity index 100% rename from src/physiomotion4d/segment_heart_simpleware_trimmed_branches.py rename to src/physiotwin4d/segment_heart_simpleware_trimmed_branches.py diff --git a/src/physiomotion4d/simpleware_medical/README.md b/src/physiotwin4d/simpleware_medical/README.md similarity index 91% rename from src/physiomotion4d/simpleware_medical/README.md rename to src/physiotwin4d/simpleware_medical/README.md index a8dc704..250e26c 100644 --- a/src/physiomotion4d/simpleware_medical/README.md +++ b/src/physiotwin4d/simpleware_medical/README.md @@ -1,10 +1,10 @@ -# Simpleware Medical Integration for PhysioMotion4D +# Simpleware Medical Integration for PhysioTwin4D -This directory contains integration code for using Synopsys Simpleware Medical with PhysioMotion4D for heart segmentation. +This directory contains integration code for using Synopsys Simpleware Medical with PhysioTwin4D for heart segmentation. ## Overview -The integration enables PhysioMotion4D to leverage Simpleware Medical's ASCardio module for automated cardiac segmentation. The implementation uses a two-component architecture: +The integration enables PhysioTwin4D to leverage Simpleware Medical's ASCardio module for automated cardiac segmentation. The implementation uses a two-component architecture: 1. **segment_heart_simpleware.py** (in parent directory): A Python class that inherits from `SegmentAnatomyBase` and manages the external Simpleware Medical process 2. **SimplewareScript_heart_segmentation.py** (this directory): A Python script that runs within the Simpleware Medical environment and performs the actual segmentation using ASCardio @@ -57,7 +57,7 @@ as_cardio = doc.GetAutoSegmenters().GetASCardio() ### Basic Usage ```python -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware import itk # Create segmenter instance @@ -111,7 +111,7 @@ The ASCardio module segments the following cardiac structures (label IDs match ` ### Process Flow -1. PhysioMotion4D preprocesses the CT image (resampling to 1 mm isotropic, intensity scaling). +1. PhysioTwin4D preprocesses the CT image (resampling to 1 mm isotropic, intensity scaling). 2. Preprocessed image is saved to a temporary NIfTI file (e.g. `input_image.nii.gz`) in a temporary directory. 3. `ConsoleSimplewareMedical.exe` is launched with: - `--input-file ` — the preprocessed CT (Simpleware opens it as the active document) @@ -122,7 +122,7 @@ The ASCardio module segments the following cardiac structures (label IDs match ` - Gets the output directory from `app.GetInputValue()` - Uses the current document (the loaded NIfTI) and ASCardio to segment heart and vessels - Exports each mask as `mask_.mhd` into the output directory -5. PhysioMotion4D reads the `mask_*.mhd` files, builds the labelmap (including heart exterior from interior regions), and returns the result. +5. PhysioTwin4D reads the `mask_*.mhd` files, builds the labelmap (including heart exterior from interior regions), and returns the result. ### Communication @@ -230,5 +230,5 @@ doc = sw.App.GetDocument() # Active document (NIfTI loaded via --input-f ## License -This integration code is part of PhysioMotion4D and follows the same license. +This integration code is part of PhysioTwin4D and follows the same license. Simpleware Medical and ASCardio are commercial products requiring separate licenses from Synopsys. diff --git a/src/physiomotion4d/simpleware_medical/SimplewareScript_heart_segmentation.py b/src/physiotwin4d/simpleware_medical/SimplewareScript_heart_segmentation.py similarity index 95% rename from src/physiomotion4d/simpleware_medical/SimplewareScript_heart_segmentation.py rename to src/physiotwin4d/simpleware_medical/SimplewareScript_heart_segmentation.py index 6aa156c..a16c0ec 100644 --- a/src/physiomotion4d/simpleware_medical/SimplewareScript_heart_segmentation.py +++ b/src/physiotwin4d/simpleware_medical/SimplewareScript_heart_segmentation.py @@ -3,7 +3,7 @@ This script is designed to run within the Synopsys Simpleware Medical environment. It uses the ASCardio module to perform automated heart segmentation on CT images. The script is called as an external process -from the PhysioMotion4D SegmentHeartSimpleware class. +from the PhysioTwin4D SegmentHeartSimpleware class. """ import os diff --git a/src/physiomotion4d/simpleware_medical/__init__.py b/src/physiotwin4d/simpleware_medical/__init__.py similarity index 61% rename from src/physiomotion4d/simpleware_medical/__init__.py rename to src/physiotwin4d/simpleware_medical/__init__.py index c9c549e..9e37b45 100644 --- a/src/physiomotion4d/simpleware_medical/__init__.py +++ b/src/physiotwin4d/simpleware_medical/__init__.py @@ -1,7 +1,7 @@ -"""Simpleware Medical integration for PhysioMotion4D. +"""Simpleware Medical integration for PhysioTwin4D. This package contains Python scripts and utilities for integrating -Synopsys Simpleware Medical with the PhysioMotion4D framework. +Synopsys Simpleware Medical with the PhysioTwin4D framework. Modules: SimplewareScript_heart_segmentation: Script for ASCardio heart segmentation diff --git a/src/physiomotion4d/test_tools.py b/src/physiotwin4d/test_tools.py similarity index 98% rename from src/physiomotion4d/test_tools.py rename to src/physiotwin4d/test_tools.py index 083e7da..bdbea40 100644 --- a/src/physiomotion4d/test_tools.py +++ b/src/physiotwin4d/test_tools.py @@ -17,9 +17,9 @@ import itk import numpy as np -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase -# Repo root: src/physiomotion4d/test_tools.py -> parent.parent.parent +# Repo root: src/physiotwin4d/test_tools.py -> parent.parent.parent _REPO_ROOT = Path(__file__).resolve().parent.parent.parent # Set by tests/conftest.py from pytest --create-baselines; applies to entire run @@ -32,10 +32,10 @@ def set_create_baseline_if_missing(value: bool) -> None: _create_baseline_if_missing = value -class TestTools(PhysioMotion4DBase): +class TestTools(PhysioTwin4DBase): """ Utilities for pytest image comparison: baseline directory, result directory, - and comparison with configurable tolerances. Inherits from PhysioMotion4DBase + and comparison with configurable tolerances. Inherits from PhysioTwin4DBase for logging. All image I/O uses ITK with compression where supported. """ @@ -109,10 +109,10 @@ def running_as_test() -> bool: for interactive or production runs. Returns: - True if PHYSIOMOTION_RUNNING_AS_TEST is set to a truthy value + True if PHYSIOTWIN_RUNNING_AS_TEST is set to a truthy value (1, true, yes, case-insensitive); False otherwise. """ - return os.environ.get("PHYSIOMOTION_RUNNING_AS_TEST", "").lower() in ( + return os.environ.get("PHYSIOTWIN_RUNNING_AS_TEST", "").lower() in ( "1", "true", "yes", diff --git a/src/physiomotion4d/transform_tools.py b/src/physiotwin4d/transform_tools.py similarity index 99% rename from src/physiomotion4d/transform_tools.py rename to src/physiotwin4d/transform_tools.py index 06daec0..401b427 100644 --- a/src/physiomotion4d/transform_tools.py +++ b/src/physiotwin4d/transform_tools.py @@ -25,13 +25,13 @@ from pxr import Gf, Sdf, Usd, UsdGeom from .image_tools import ImageTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .vtk_to_usd import add_framing_camera FloatArray: TypeAlias = NDArray[np.float32] | NDArray[np.float64] -class TransformTools(PhysioMotion4DBase): +class TransformTools(PhysioTwin4DBase): """ Utilities for transforming and manipulating ITK transforms. diff --git a/src/physiomotion4d/usd_anatomy_tools.py b/src/physiotwin4d/usd_anatomy_tools.py similarity index 98% rename from src/physiomotion4d/usd_anatomy_tools.py rename to src/physiotwin4d/usd_anatomy_tools.py index 9125767..0efd5d8 100644 --- a/src/physiomotion4d/usd_anatomy_tools.py +++ b/src/physiotwin4d/usd_anatomy_tools.py @@ -11,7 +11,7 @@ 1. **Globally**, before instantiating any ``USDAnatomyTools``:: - from physiomotion4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS + from physiotwin4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS DEFAULT_RENDER_PARAMS["brain"] = {"name": "Brain", ...} Every subsequent ``USDAnatomyTools`` instance picks up the new entry. @@ -26,7 +26,7 @@ Group lookup falls back to ``render_params["other"]`` when a group has no registered entry, so any group present in the segmenter's -:class:`physiomotion4d.AnatomyTaxonomy` will still render *something*. +:class:`physiotwin4d.AnatomyTaxonomy` will still render *something*. """ import logging @@ -34,10 +34,10 @@ from pxr import Sdf, UsdGeom, UsdShade -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase # Default OmniSurface render parameters keyed by group name (matching -# :class:`physiomotion4d.AnatomyTaxonomy.group_names`) and by organ-level +# :class:`physiotwin4d.AnatomyTaxonomy.group_names`) and by organ-level # overrides (e.g. ``liver``, ``spleen``, ``kidney_left``). ``enhance_meshes`` # consults an organ-level entry first, then falls back to the containing # group's entry, and finally to ``"other"``. Module-level so CLIs and tests @@ -204,7 +204,7 @@ DEFAULT_RENDER_PARAMS["kidney"] = DEFAULT_RENDER_PARAMS["kidney_right"] -class USDAnatomyTools(PhysioMotion4DBase): +class USDAnatomyTools(PhysioTwin4DBase): """Apply OmniSurface materials to anatomy mesh prims in a USD stage. The instance attribute :attr:`render_params` is initialized from the diff --git a/src/physiomotion4d/usd_tools.py b/src/physiotwin4d/usd_tools.py similarity index 99% rename from src/physiomotion4d/usd_tools.py rename to src/physiotwin4d/usd_tools.py index 3e2af6a..5161701 100644 --- a/src/physiomotion4d/usd_tools.py +++ b/src/physiotwin4d/usd_tools.py @@ -21,11 +21,11 @@ import pyvista as pvtk from pxr import Gf, Sdf, Usd, UsdGeom, UsdShade -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .vtk_to_usd import add_framing_camera -class USDTools(PhysioMotion4DBase): +class USDTools(PhysioTwin4DBase): """ Utilities for manipulating Universal Scene Description (USD) files. diff --git a/src/physiomotion4d/vtk_to_usd/CLAUDE.md b/src/physiotwin4d/vtk_to_usd/CLAUDE.md similarity index 86% rename from src/physiomotion4d/vtk_to_usd/CLAUDE.md rename to src/physiotwin4d/vtk_to_usd/CLAUDE.md index 225a1d4..a3bb7e1 100644 --- a/src/physiomotion4d/vtk_to_usd/CLAUDE.md +++ b/src/physiotwin4d/vtk_to_usd/CLAUDE.md @@ -6,14 +6,14 @@ touching it. ## Preferred In-Repo API Do not add calls to `vtk_to_usd` from experiments, workflows, CLIs, or other -top-level PhysioMotion4D modules. The in-repository entry point for VTK-to-USD +top-level PhysioTwin4D modules. The in-repository entry point for VTK-to-USD conversion is: ```python -from physiomotion4d.convert_vtk_to_usd import ConvertVTKToUSD +from physiotwin4d.convert_vtk_to_usd import ConvertVTKToUSD ``` -External advanced users may import `physiomotion4d.vtk_to_usd` directly. +External advanced users may import `physiotwin4d.vtk_to_usd` directly. ## Role of This Subpackage @@ -46,7 +46,7 @@ single-file facade. Otherwise, prefer `convert_vtk_to_usd.py`. LPS-to-USD-Y-up conversion: `USD(x, y, z) = LPS(x, z, -y) * 0.001`. -PhysioMotion4D keeps images and surfaces in ITK's native LPS frame; the +PhysioTwin4D keeps images and surfaces in ITK's native LPS frame; the resulting USD frame is right-handed Y-up with USD +X = patient Left, USD +Y = patient Superior, USD +Z = patient Anterior. diff --git a/src/physiomotion4d/vtk_to_usd/README.md b/src/physiotwin4d/vtk_to_usd/README.md similarity index 91% rename from src/physiomotion4d/vtk_to_usd/README.md rename to src/physiotwin4d/vtk_to_usd/README.md index ad9ff0f..7623f34 100644 --- a/src/physiomotion4d/vtk_to_usd/README.md +++ b/src/physiotwin4d/vtk_to_usd/README.md @@ -1,7 +1,7 @@ # VTK to USD Advanced Library -`physiomotion4d.vtk_to_usd` is the public low-level VTK-to-USD conversion -layer used by `physiomotion4d.ConvertVTKToUSD`. +`physiotwin4d.vtk_to_usd` is the public low-level VTK-to-USD conversion +layer used by `physiotwin4d.ConvertVTKToUSD`. Repository workflows, experiments, and CLIs should use `ConvertVTKToUSD`. Import this subpackage directly only when you need advanced file readers, data @@ -34,7 +34,7 @@ vtk_to_usd/ ## Quick Start ```python -from physiomotion4d.vtk_to_usd import convert_vtk_file +from physiotwin4d.vtk_to_usd import convert_vtk_file stage = convert_vtk_file('mesh.vtp', 'output.usd') ``` @@ -42,7 +42,7 @@ stage = convert_vtk_file('mesh.vtp', 'output.usd') ## Custom Settings ```python -from physiomotion4d.vtk_to_usd import ( +from physiotwin4d.vtk_to_usd import ( ConversionSettings, MaterialData, convert_vtk_file, @@ -76,7 +76,7 @@ Use the high-level package API for time series, colormaps, labels, and application workflows: ```python -from physiomotion4d import ConvertVTKToUSD +from physiotwin4d import ConvertVTKToUSD stage = ConvertVTKToUSD.from_files( data_basename='AnimatedMesh', @@ -88,7 +88,7 @@ stage = ConvertVTKToUSD.from_files( ## MeshData Inspection ```python -from physiomotion4d.vtk_to_usd import read_vtk_file +from physiotwin4d.vtk_to_usd import read_vtk_file mesh_data = read_vtk_file('mesh.vtp') print(len(mesh_data.points)) diff --git a/src/physiomotion4d/vtk_to_usd/__init__.py b/src/physiotwin4d/vtk_to_usd/__init__.py similarity index 89% rename from src/physiomotion4d/vtk_to_usd/__init__.py rename to src/physiotwin4d/vtk_to_usd/__init__.py index fbc701d..1af9cc1 100644 --- a/src/physiomotion4d/vtk_to_usd/__init__.py +++ b/src/physiotwin4d/vtk_to_usd/__init__.py @@ -1,8 +1,8 @@ -"""Public advanced VTK-to-USD conversion layer for PhysioMotion4D. +"""Public advanced VTK-to-USD conversion layer for PhysioTwin4D. This subpackage is a stable low-level API for advanced external users. Code in -PhysioMotion4D experiments, workflows, and CLIs should use ConvertVTKToUSD from -physiomotion4d.convert_vtk_to_usd instead of importing this package directly. +PhysioTwin4D experiments, workflows, and CLIs should use ConvertVTKToUSD from +physiotwin4d.convert_vtk_to_usd instead of importing this package directly. Provides: - File facade: convert_vtk_file diff --git a/src/physiomotion4d/vtk_to_usd/converter.py b/src/physiotwin4d/vtk_to_usd/converter.py similarity index 97% rename from src/physiomotion4d/vtk_to_usd/converter.py rename to src/physiotwin4d/vtk_to_usd/converter.py index 5d0c144..5c67941 100644 --- a/src/physiomotion4d/vtk_to_usd/converter.py +++ b/src/physiotwin4d/vtk_to_usd/converter.py @@ -26,7 +26,7 @@ def convert_vtk_file( This is the stable low-level facade for advanced users who want the file-based vtk_to_usd conversion layer directly. In-repository workflows, - experiments, and CLIs should use :class:`physiomotion4d.ConvertVTKToUSD` + experiments, and CLIs should use :class:`physiotwin4d.ConvertVTKToUSD` instead. Args: diff --git a/src/physiomotion4d/vtk_to_usd/data_structures.py b/src/physiotwin4d/vtk_to_usd/data_structures.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/data_structures.py rename to src/physiotwin4d/vtk_to_usd/data_structures.py diff --git a/src/physiomotion4d/vtk_to_usd/material_manager.py b/src/physiotwin4d/vtk_to_usd/material_manager.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/material_manager.py rename to src/physiotwin4d/vtk_to_usd/material_manager.py diff --git a/src/physiomotion4d/vtk_to_usd/mesh_utils.py b/src/physiotwin4d/vtk_to_usd/mesh_utils.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/mesh_utils.py rename to src/physiotwin4d/vtk_to_usd/mesh_utils.py diff --git a/src/physiomotion4d/vtk_to_usd/primvar_derivations.py b/src/physiotwin4d/vtk_to_usd/primvar_derivations.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/primvar_derivations.py rename to src/physiotwin4d/vtk_to_usd/primvar_derivations.py diff --git a/src/physiomotion4d/vtk_to_usd/usd_mesh_converter.py b/src/physiotwin4d/vtk_to_usd/usd_mesh_converter.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/usd_mesh_converter.py rename to src/physiotwin4d/vtk_to_usd/usd_mesh_converter.py diff --git a/src/physiomotion4d/vtk_to_usd/usd_utils.py b/src/physiotwin4d/vtk_to_usd/usd_utils.py similarity index 99% rename from src/physiomotion4d/vtk_to_usd/usd_utils.py rename to src/physiotwin4d/vtk_to_usd/usd_utils.py index 0406580..7408bc1 100644 --- a/src/physiomotion4d/vtk_to_usd/usd_utils.py +++ b/src/physiotwin4d/vtk_to_usd/usd_utils.py @@ -20,7 +20,7 @@ def lps_to_usd(point: NDArray | tuple | list) -> Gf.Vec3f: """Convert LPS (Left-Posterior-Superior) coordinates to USD's right-handed Y-up frame. - PhysioMotion4D keeps images and surfaces in ITK's native LPS world space. + PhysioTwin4D keeps images and surfaces in ITK's native LPS world space. ``itk.imread`` normalizes every supported input (DICOM, NIfTI, MHA, NRRD) to LPS, and ``itk.vtk_image_from_image`` preserves that frame when handing data to PyVista/VTK, so meshes extracted via ``contour_labels`` diff --git a/src/physiomotion4d/vtk_to_usd/vtk_reader.py b/src/physiotwin4d/vtk_to_usd/vtk_reader.py similarity index 100% rename from src/physiomotion4d/vtk_to_usd/vtk_reader.py rename to src/physiotwin4d/vtk_to_usd/vtk_reader.py diff --git a/src/physiomotion4d/workflow_convert_image_to_usd.py b/src/physiotwin4d/workflow_convert_image_to_usd.py similarity index 99% rename from src/physiomotion4d/workflow_convert_image_to_usd.py rename to src/physiotwin4d/workflow_convert_image_to_usd.py index b537d96..35bdbb5 100644 --- a/src/physiomotion4d/workflow_convert_image_to_usd.py +++ b/src/physiotwin4d/workflow_convert_image_to_usd.py @@ -4,7 +4,7 @@ This module implements the complete pipeline for processing 3D or 4D medical images (e.g. cardiac and respiratory gated CT studies) into dynamic USD models. 4D image arrays follow the (X, Y, Z, T) axis convention used -throughout PhysioMotion4D. +throughout PhysioTwin4D. """ import logging @@ -18,7 +18,7 @@ from .contour_tools import ContourTools from .convert_vtk_to_usd import ConvertVTKToUSD from .image_tools import ImageTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_base import RegisterImagesBase from .register_images_icon import RegisterImagesICON from .segment_anatomy_base import SegmentAnatomyBase @@ -29,7 +29,7 @@ from .usd_anatomy_tools import USDAnatomyTools -class WorkflowConvertImageToUSD(PhysioMotion4DBase): +class WorkflowConvertImageToUSD(PhysioTwin4DBase): """ Complete workflow for converting 4D CT images to dynamic USD models. diff --git a/src/physiomotion4d/workflow_convert_image_to_vtk.py b/src/physiotwin4d/workflow_convert_image_to_vtk.py similarity index 98% rename from src/physiomotion4d/workflow_convert_image_to_vtk.py rename to src/physiotwin4d/workflow_convert_image_to_vtk.py index 0fcc739..2770a93 100644 --- a/src/physiomotion4d/workflow_convert_image_to_vtk.py +++ b/src/physiotwin4d/workflow_convert_image_to_vtk.py @@ -10,7 +10,7 @@ Typical usage:: import itk - from physiomotion4d import ( + from physiotwin4d import ( SegmentChestTotalSegmentatorWithContrast, WorkflowConvertImageToVTK, ) @@ -39,7 +39,7 @@ import pyvista as pv from .contour_tools import ContourTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .segment_anatomy_base import SegmentAnatomyBase from .segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, @@ -47,7 +47,7 @@ from .usd_anatomy_tools import USDAnatomyTools -class WorkflowConvertImageToVTK(PhysioMotion4DBase): +class WorkflowConvertImageToVTK(PhysioTwin4DBase): """Segment a CT image and produce per-anatomy-group VTK surfaces and meshes. ``segmentation_method`` accepts a pre-configured @@ -83,7 +83,7 @@ class WorkflowConvertImageToVTK(PhysioMotion4DBase): :meth:`ContourTools.save_surfaces`, :meth:`ContourTools.save_meshes`, :meth:`ContourTools.save_combined_surface`, and :meth:`ContourTools.save_combined_mesh` — or the CLI - ``physiomotion4d-convert-image-to-vtk`` — to write results to disk. + ``physiotwin4d-convert-image-to-vtk`` — to write results to disk. """ def __init__( diff --git a/src/physiomotion4d/workflow_convert_vtk_to_usd.py b/src/physiotwin4d/workflow_convert_vtk_to_usd.py similarity index 99% rename from src/physiomotion4d/workflow_convert_vtk_to_usd.py rename to src/physiotwin4d/workflow_convert_vtk_to_usd.py index e3b8696..89fd6c9 100644 --- a/src/physiomotion4d/workflow_convert_vtk_to_usd.py +++ b/src/physiotwin4d/workflow_convert_vtk_to_usd.py @@ -13,14 +13,14 @@ from typing import Literal from .convert_vtk_to_usd import ConvertVTKToUSD -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .usd_anatomy_tools import USDAnatomyTools from .usd_tools import USDTools AppearanceKind = Literal["solid", "anatomy", "colormap"] -class WorkflowConvertVTKToUSD(PhysioMotion4DBase): +class WorkflowConvertVTKToUSD(PhysioTwin4DBase): """ Workflow to convert one or more VTK files to USD with configurable splitting and appearance (solid color, anatomic material, or colormap). diff --git a/src/physiomotion4d/workflow_create_statistical_model.py b/src/physiotwin4d/workflow_create_statistical_model.py similarity index 99% rename from src/physiomotion4d/workflow_create_statistical_model.py rename to src/physiotwin4d/workflow_create_statistical_model.py index ef6014d..42c373f 100644 --- a/src/physiomotion4d/workflow_create_statistical_model.py +++ b/src/physiotwin4d/workflow_create_statistical_model.py @@ -17,7 +17,7 @@ from sklearn.decomposition import PCA from .contour_tools import ContourTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_models_distance_maps import RegisterModelsDistanceMaps from .register_models_icp import RegisterModelsICP from .transform_tools import TransformTools @@ -32,7 +32,7 @@ def _extract_surface(mesh: pv.DataSet) -> pv.PolyData: return mesh.extract_surface(algorithm="dataset_surface") -class WorkflowCreateStatisticalModel(PhysioMotion4DBase): +class WorkflowCreateStatisticalModel(PhysioTwin4DBase): """Create a PCA statistical shape model from a sample of meshes aligned to a reference. Pipeline: diff --git a/src/physiomotion4d/workflow_fine_tune_icon_registration.py b/src/physiotwin4d/workflow_fine_tune_icon_registration.py similarity index 99% rename from src/physiomotion4d/workflow_fine_tune_icon_registration.py rename to src/physiotwin4d/workflow_fine_tune_icon_registration.py index 2ce9304..0faf83a 100644 --- a/src/physiomotion4d/workflow_fine_tune_icon_registration.py +++ b/src/physiotwin4d/workflow_fine_tune_icon_registration.py @@ -38,7 +38,7 @@ import yaml from .labelmap_tools import LabelmapTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_icon import RegisterImagesICON from .register_time_series_images import RegisterTimeSeriesImages from .transform_tools import TransformTools @@ -46,7 +46,7 @@ Landmarks = dict[str, tuple[float, float, float]] -class WorkflowFineTuneICONRegistration(PhysioMotion4DBase): +class WorkflowFineTuneICONRegistration(PhysioTwin4DBase): """Fine-tune uniGradICON on paired 3D images and apply the fine-tuned weights. The workflow has two stages that can be used together or independently: @@ -109,7 +109,7 @@ class WorkflowFineTuneICONRegistration(PhysioMotion4DBase): ... ['pm0001/g000.nii.gz', 'pm0001/g050.nii.gz'], ... ['pm0002/g000.nii.gz', 'pm0002/g050.nii.gz'], ... ], - ... output_dir=Path('d:/PhysioMotion4D/icon_finetuned'), + ... output_dir=Path('d:/PhysioTwin4D/icon_finetuned'), ... fine_tune_name='duke_4d_gated_icon_ft', ... subject_labelmap_files=[ ... ['pm0001/g000_labelmap.nii.gz', 'pm0001/g050_labelmap.nii.gz'], diff --git a/src/physiomotion4d/workflow_fit_statistical_model_to_patient.py b/src/physiotwin4d/workflow_fit_statistical_model_to_patient.py similarity index 99% rename from src/physiomotion4d/workflow_fit_statistical_model_to_patient.py rename to src/physiotwin4d/workflow_fit_statistical_model_to_patient.py index bbedfc5..dab5bcb 100644 --- a/src/physiomotion4d/workflow_fit_statistical_model_to_patient.py +++ b/src/physiotwin4d/workflow_fit_statistical_model_to_patient.py @@ -32,7 +32,7 @@ from .contour_tools import ContourTools from .image_tools import ImageTools from .labelmap_tools import LabelmapTools -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_greedy import RegisterImagesGreedy from .register_images_icon import RegisterImagesICON from .register_models_distance_maps import RegisterModelsDistanceMaps @@ -46,7 +46,7 @@ from .workflow_convert_image_to_vtk import WorkflowConvertImageToVTK -class WorkflowFitStatisticalModelToPatient(PhysioMotion4DBase): +class WorkflowFitStatisticalModelToPatient(PhysioTwin4DBase): """Register anatomical models using multi-stage ICP, labelmap-based, and image-based registration. diff --git a/src/physiomotion4d/workflow_reconstruct_highres_4d_ct.py b/src/physiotwin4d/workflow_reconstruct_highres_4d_ct.py similarity index 99% rename from src/physiomotion4d/workflow_reconstruct_highres_4d_ct.py rename to src/physiotwin4d/workflow_reconstruct_highres_4d_ct.py index 66641fd..c074cfe 100644 --- a/src/physiomotion4d/workflow_reconstruct_highres_4d_ct.py +++ b/src/physiotwin4d/workflow_reconstruct_highres_4d_ct.py @@ -28,12 +28,12 @@ import itk -from .physiomotion4d_base import PhysioMotion4DBase +from .physiotwin4d_base import PhysioTwin4DBase from .register_images_base import RegisterImagesBase from .register_time_series_images import RegisterTimeSeriesImages -class WorkflowReconstructHighres4DCT(PhysioMotion4DBase): +class WorkflowReconstructHighres4DCT(PhysioTwin4DBase): """Reconstruct high-resolution 4D CT from time series and reference image. This class implements a workflow for reconstructing high-resolution dynamic diff --git a/tests/README.md b/tests/README.md index decd103..ad4adaa 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,6 @@ -# PhysioMotion4D Tests +# PhysioTwin4D Tests -This directory contains comprehensive test suites for the PhysioMotion4D package, validating the complete medical imaging to Omniverse pipeline. +This directory contains comprehensive test suites for the PhysioTwin4D package, validating the complete medical imaging to Omniverse pipeline. ## Documentation @@ -132,7 +132,7 @@ pytest tests/test_experiments.py::test_experiment_heart_gated_ct_to_usd -v -s -- ### Common Test Commands ```bash # Run with coverage -pytest tests/ --cov=src/physiomotion4d --cov-report=html +pytest tests/ --cov=src/physiotwin4d --cov-report=html # Run a specific test class or method pytest tests/test_usd_merge.py::TestUSDMerge::test_merge_usd_files_copy_method -v @@ -161,7 +161,7 @@ All test runs automatically generate a comprehensive timing report at the end sh Simpleware Medical install. Opt in: `--run-simpleware`. (Combine with `--run-gpu` and `--run-slow`.) - `@pytest.mark.requires_physicsnemo` — Tests needing the optional - `[physicsnemo]` extra (`pip install "physiomotion4d[physicsnemo]"`, requires + `[physicsnemo]` extra (`pip install "physiotwin4d[physicsnemo]"`, requires Python >= 3.11). Opt in: `--run-physicsnemo`. - `@pytest.mark.experiment` — End-to-end experiment notebooks (EXTREMELY SLOW, never in CI). Opt in: `--run-experiments`. diff --git a/tests/__init__.py b/tests/__init__.py index 74fd91a..7f4d080 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,5 @@ """ -PhysioMotion4D test suite. +PhysioTwin4D test suite. -This package contains integration and regression tests for the PhysioMotion4D pipeline. +This package contains integration and regression tests for the PhysioTwin4D pipeline. """ diff --git a/tests/conftest.py b/tests/conftest.py index f6a2457..3e13c68 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,6 @@ #!/usr/bin/env python """ -Shared pytest fixtures for PhysioMotion4D tests. +Shared pytest fixtures for PhysioTwin4D tests. This file defines fixtures that are available to all test modules in the tests directory via pytest's automatic fixture discovery. @@ -14,18 +14,18 @@ import itk import pytest -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.convert_image_4d_to_3d import ConvertImage4DTo3D -from physiomotion4d.data_download_tools import DataDownloadTools -from physiomotion4d.register_images_ants import RegisterImagesANTS -from physiomotion4d.register_images_greedy import RegisterImagesGreedy -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.convert_image_4d_to_3d import ConvertImage4DTo3D +from physiotwin4d.data_download_tools import DataDownloadTools +from physiotwin4d.register_images_ants import RegisterImagesANTS +from physiotwin4d.register_images_greedy import RegisterImagesGreedy +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.transform_tools import TransformTools # ============================================================================ # Pytest Configuration - Command Line Options @@ -116,7 +116,7 @@ def pytest_configure(config: pytest.Config) -> None: global _pytest_config _pytest_config = config - from physiomotion4d import test_tools as _test_tools + from physiotwin4d import test_tools as _test_tools _test_tools.set_create_baseline_if_missing( config.getoption("--create-baselines", default=False) diff --git a/tests/test_anatomy_taxonomy.py b/tests/test_anatomy_taxonomy.py index 2c6c633..f64eced 100644 --- a/tests/test_anatomy_taxonomy.py +++ b/tests/test_anatomy_taxonomy.py @@ -1,4 +1,4 @@ -"""Unit tests for :class:`physiomotion4d.AnatomyTaxonomy`. +"""Unit tests for :class:`physiotwin4d.AnatomyTaxonomy`. These tests exercise the pure-data taxonomy in isolation — no ITK, no pxr, no GPU. They are fast and run unconditionally in the default test suite. @@ -8,7 +8,7 @@ import pytest -from physiomotion4d import AnatomyGroup, AnatomyTaxonomy +from physiotwin4d import AnatomyGroup, AnatomyTaxonomy def test_add_organ_creates_group_lazily() -> None: @@ -116,7 +116,7 @@ def test_anatomy_group_dataclass_default_organs() -> None: def test_segment_anatomy_base_default_taxonomy_seeded() -> None: # Import lazily to avoid pulling itk in test collection if it's unused # by sibling tests in this module. - from physiomotion4d import SegmentAnatomyBase + from physiotwin4d import SegmentAnatomyBase seg = SegmentAnatomyBase() assert len(seg.taxonomy.all_labels()) == 0 diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index e7522b1..ce9f145 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -11,15 +11,15 @@ CLI_MODULES = [ - "physiomotion4d.cli.convert_image_to_vtk", - "physiomotion4d.cli.convert_image_4d_to_3d", - "physiomotion4d.cli.convert_image_to_usd", - "physiomotion4d.cli.convert_vtk_to_usd", - "physiomotion4d.cli.create_statistical_model", - "physiomotion4d.cli.download_data", - "physiomotion4d.cli.fit_statistical_model_to_patient", - "physiomotion4d.cli.reconstruct_highres_4d_ct", - "physiomotion4d.cli.visualize_pca_modes", + "physiotwin4d.cli.convert_image_to_vtk", + "physiotwin4d.cli.convert_image_4d_to_3d", + "physiotwin4d.cli.convert_image_to_usd", + "physiotwin4d.cli.convert_vtk_to_usd", + "physiotwin4d.cli.create_statistical_model", + "physiotwin4d.cli.download_data", + "physiotwin4d.cli.fit_statistical_model_to_patient", + "physiotwin4d.cli.reconstruct_highres_4d_ct", + "physiotwin4d.cli.visualize_pca_modes", ] @@ -46,7 +46,7 @@ def test_convert_image_to_usd_help_includes_fps( capsys: pytest.CaptureFixture[str], ) -> None: """Image-to-USD CLI exposes playback FPS for animated USD output.""" - module = importlib.import_module("physiomotion4d.cli.convert_image_to_usd") + module = importlib.import_module("physiotwin4d.cli.convert_image_to_usd") monkeypatch.setattr(sys, "argv", ["convert_image_to_usd", "--help"]) with pytest.raises(SystemExit) as exc_info: @@ -62,9 +62,9 @@ def test_convert_image_to_usd_cli_passes_fps( tmp_path: Path, ) -> None: """Image-to-USD CLI forwards --fps as times_per_second.""" - import physiomotion4d + import physiotwin4d - module = importlib.import_module("physiomotion4d.cli.convert_image_to_usd") + module = importlib.import_module("physiotwin4d.cli.convert_image_to_usd") input_file = tmp_path / "input.mha" input_file.write_text("placeholder") captured_kwargs: dict[str, Any] = {} @@ -90,7 +90,7 @@ def process(self) -> str: FakeConvertImage4DTo3D, ) monkeypatch.setattr( - physiomotion4d, + physiotwin4d, "WorkflowConvertImageToUSD", FakeWorkflowConvertImageToUSD, ) diff --git a/tests/test_contour_tools.py b/tests/test_contour_tools.py index c095eb7..010a5f8 100644 --- a/tests/test_contour_tools.py +++ b/tests/test_contour_tools.py @@ -14,7 +14,7 @@ import pytest import pyvista as pv -from physiomotion4d.contour_tools import ContourTools +from physiotwin4d.contour_tools import ContourTools @pytest.mark.slow diff --git a/tests/test_convert_image_4d_to_3d.py b/tests/test_convert_image_4d_to_3d.py index d7442ca..aa8eff8 100644 --- a/tests/test_convert_image_4d_to_3d.py +++ b/tests/test_convert_image_4d_to_3d.py @@ -10,7 +10,7 @@ import pytest -from physiomotion4d.convert_image_4d_to_3d import ConvertImage4DTo3D +from physiotwin4d.convert_image_4d_to_3d import ConvertImage4DTo3D class TestConvertImage4DTo3D: diff --git a/tests/test_convert_vtk_to_usd.py b/tests/test_convert_vtk_to_usd.py index 27616c2..3bf626d 100644 --- a/tests/test_convert_vtk_to_usd.py +++ b/tests/test_convert_vtk_to_usd.py @@ -15,8 +15,8 @@ import pyvista as pv from pxr import UsdGeom -from physiomotion4d import ConvertVTKToUSD -from physiomotion4d.contour_tools import ContourTools +from physiotwin4d import ConvertVTKToUSD +from physiotwin4d.contour_tools import ContourTools def _make_poly(label_ids: list[int] | None = None) -> pv.PolyData: @@ -577,7 +577,7 @@ def test_mask_ids_missing_boundary_labels_falls_back(self, tmp_path: Path) -> No def test_mask_ids_groups_by_segmenter_type(self, tmp_path: Path) -> None: """When a segmenter is supplied, labels are grouped under their anatomy type (heart/lung/...) for both meshes and materials.""" - from physiomotion4d.segment_chest_total_segmentator import ( + from physiotwin4d.segment_chest_total_segmentator import ( SegmentChestTotalSegmentator, ) diff --git a/tests/test_download_data_cli.py b/tests/test_download_data_cli.py index df6c567..8c05e7b 100644 --- a/tests/test_download_data_cli.py +++ b/tests/test_download_data_cli.py @@ -7,8 +7,8 @@ import pytest -from physiomotion4d.cli import download_data -from physiomotion4d.data_download_tools import DataDownloadTools +from physiotwin4d.cli import download_data +from physiotwin4d.data_download_tools import DataDownloadTools def test_download_data_cli_uses_default_dataset_and_directory( diff --git a/tests/test_download_heart_data.py b/tests/test_download_heart_data.py index 905fb97..2893ddc 100644 --- a/tests/test_download_heart_data.py +++ b/tests/test_download_heart_data.py @@ -10,7 +10,7 @@ import pytest -from physiomotion4d.data_download_tools import DataDownloadTools +from physiotwin4d.data_download_tools import DataDownloadTools class TestDataDownloadTools: diff --git a/tests/test_experiments.py b/tests/test_experiments.py index 92575e8..5060f9d 100644 --- a/tests/test_experiments.py +++ b/tests/test_experiments.py @@ -99,7 +99,7 @@ def execute_script(script_path: Path, timeout: int = 3600) -> dict[str, Any]: # So scripts can use reduced parameters when run as tests env = os.environ.copy() - env["PHYSIOMOTION_RUNNING_AS_TEST"] = "1" + env["PHYSIOTWIN_RUNNING_AS_TEST"] = "1" try: result = subprocess.run( diff --git a/tests/test_image_tools.py b/tests/test_image_tools.py index b893446..a1edbc0 100644 --- a/tests/test_image_tools.py +++ b/tests/test_image_tools.py @@ -16,7 +16,7 @@ import pytest import SimpleITK as sitk -from physiomotion4d.image_tools import ImageTools +from physiotwin4d.image_tools import ImageTools class TestImageTools: @@ -245,7 +245,7 @@ def test_imwrite_imread_vd3( test_directories: dict[str, Path], ) -> None: """Test reading and writing double precision vector images.""" - from physiomotion4d.transform_tools import TransformTools + from physiotwin4d.transform_tools import TransformTools output_dir = test_directories["output"] img_output_dir = output_dir / "image_tools" diff --git a/tests/test_import_public_api.py b/tests/test_import_public_api.py index 802af79..15d80a3 100644 --- a/tests/test_import_public_api.py +++ b/tests/test_import_public_api.py @@ -7,14 +7,14 @@ def test_public_api_exports_are_importable() -> None: - """Every name in physiomotion4d.__all__ resolves from the package.""" - package = importlib.import_module("physiomotion4d") + """Every name in physiotwin4d.__all__ resolves from the package.""" + package = importlib.import_module("physiotwin4d") public_names = getattr(package, "__all__", None) assert isinstance(public_names, Sequence), ( - "physiomotion4d.__all__ should be a sequence of public export names" + "physiotwin4d.__all__ should be a sequence of public export names" ) - assert public_names, "physiomotion4d.__all__ should not be empty" + assert public_names, "physiotwin4d.__all__ should not be empty" for name in public_names: assert hasattr(package, name), f"Missing public export: {name}" diff --git a/tests/test_labelmap_tools.py b/tests/test_labelmap_tools.py index 6e1279c..ed0df03 100644 --- a/tests/test_labelmap_tools.py +++ b/tests/test_labelmap_tools.py @@ -13,7 +13,7 @@ import numpy as np import pytest -from physiomotion4d.labelmap_tools import LabelmapTools +from physiotwin4d.labelmap_tools import LabelmapTools class TestLabelmapTools: diff --git a/tests/test_register_images_ants.py b/tests/test_register_images_ants.py index 61c778d..a36fe41 100644 --- a/tests/test_register_images_ants.py +++ b/tests/test_register_images_ants.py @@ -16,8 +16,8 @@ import numpy as np import pytest -from physiomotion4d.register_images_ants import RegisterImagesANTS -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.register_images_ants import RegisterImagesANTS +from physiotwin4d.transform_tools import TransformTools def _foreground_ncc( @@ -869,7 +869,7 @@ def test_transform_conversion_cycle_displacement_field( # Create a simple displacement field with double precision # Use ImageTools to create the correct type - from physiomotion4d.image_tools import ImageTools + from physiotwin4d.image_tools import ImageTools image_tools = ImageTools() diff --git a/tests/test_register_images_chain.py b/tests/test_register_images_chain.py index ea3c03e..26e999c 100644 --- a/tests/test_register_images_chain.py +++ b/tests/test_register_images_chain.py @@ -16,8 +16,8 @@ import numpy as np import pytest -from physiomotion4d.register_images_base import RegisterImagesBase -from physiomotion4d.register_images_chain import RegisterImagesChain +from physiotwin4d.register_images_base import RegisterImagesBase +from physiotwin4d.register_images_chain import RegisterImagesChain def _small_image(value: float = 0.0) -> itk.Image: diff --git a/tests/test_register_images_greedy.py b/tests/test_register_images_greedy.py index dfbe314..b832060 100644 --- a/tests/test_register_images_greedy.py +++ b/tests/test_register_images_greedy.py @@ -13,8 +13,8 @@ import numpy as np import pytest -from physiomotion4d.register_images_greedy import RegisterImagesGreedy -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.register_images_greedy import RegisterImagesGreedy +from physiotwin4d.transform_tools import TransformTools @pytest.mark.slow diff --git a/tests/test_register_images_greedy_icon.py b/tests/test_register_images_greedy_icon.py index 33ad9b6..141ef79 100644 --- a/tests/test_register_images_greedy_icon.py +++ b/tests/test_register_images_greedy_icon.py @@ -12,10 +12,10 @@ import pytest -from physiomotion4d.register_images_chain import RegisterImagesChain -from physiomotion4d.register_images_greedy import RegisterImagesGreedy -from physiomotion4d.register_images_greedy_icon import RegisterImagesGreedyICON -from physiomotion4d.register_images_icon import RegisterImagesICON +from physiotwin4d.register_images_chain import RegisterImagesChain +from physiotwin4d.register_images_greedy import RegisterImagesGreedy +from physiotwin4d.register_images_greedy_icon import RegisterImagesGreedyICON +from physiotwin4d.register_images_icon import RegisterImagesICON def test_greedy_icon_is_a_two_stage_chain() -> None: diff --git a/tests/test_register_images_icon.py b/tests/test_register_images_icon.py index 998852e..c700987 100644 --- a/tests/test_register_images_icon.py +++ b/tests/test_register_images_icon.py @@ -14,8 +14,8 @@ import numpy as np import pytest -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.transform_tools import TransformTools @pytest.mark.requires_gpu diff --git a/tests/test_register_models_pca.py b/tests/test_register_models_pca.py index 32b7ea2..66b1974 100644 --- a/tests/test_register_models_pca.py +++ b/tests/test_register_models_pca.py @@ -9,7 +9,7 @@ import pytest import pyvista as pv -from physiomotion4d.register_models_pca import RegisterModelsPCA +from physiotwin4d.register_models_pca import RegisterModelsPCA def _make_registrar() -> RegisterModelsPCA: diff --git a/tests/test_register_time_series_images.py b/tests/test_register_time_series_images.py index 1584f86..9db3c9a 100644 --- a/tests/test_register_time_series_images.py +++ b/tests/test_register_time_series_images.py @@ -13,7 +13,7 @@ import numpy as np import pytest -from physiomotion4d import ( +from physiotwin4d import ( RegisterImagesGreedy, RegisterImagesGreedyICON, RegisterImagesICON, diff --git a/tests/test_segment_chest_total_segmentator.py b/tests/test_segment_chest_total_segmentator.py index ca4d8df..cb0b962 100644 --- a/tests/test_segment_chest_total_segmentator.py +++ b/tests/test_segment_chest_total_segmentator.py @@ -13,8 +13,8 @@ import numpy as np import pytest -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) diff --git a/tests/test_segment_heart_simpleware.py b/tests/test_segment_heart_simpleware.py index 3640bf4..3d5cb9b 100644 --- a/tests/test_segment_heart_simpleware.py +++ b/tests/test_segment_heart_simpleware.py @@ -17,7 +17,7 @@ import numpy as np import pytest -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware def _simpleware_available(segmenter: SegmentHeartSimpleware) -> bool: diff --git a/tests/test_segment_heart_simpleware_trimmed_branches.py b/tests/test_segment_heart_simpleware_trimmed_branches.py index 3da6e76..96847a9 100644 --- a/tests/test_segment_heart_simpleware_trimmed_branches.py +++ b/tests/test_segment_heart_simpleware_trimmed_branches.py @@ -12,8 +12,8 @@ import numpy as np import pytest -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware -from physiomotion4d.segment_heart_simpleware_trimmed_branches import ( +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.segment_heart_simpleware_trimmed_branches import ( SegmentHeartSimplewareTrimmedBranches, ) diff --git a/tests/test_transform_tools.py b/tests/test_transform_tools.py index 75e16de..b90b06c 100644 --- a/tests/test_transform_tools.py +++ b/tests/test_transform_tools.py @@ -15,8 +15,8 @@ import pyvista as pv import vtk -from physiomotion4d.image_tools import ImageTools -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.image_tools import ImageTools +from physiotwin4d.transform_tools import TransformTools def test_generate_grid_image_clamps_boundary_lines() -> None: diff --git a/tests/test_tutorials.py b/tests/test_tutorials.py index 9fcc372..5abb201 100644 --- a/tests/test_tutorials.py +++ b/tests/test_tutorials.py @@ -29,7 +29,7 @@ import pytest -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # Tolerances for screenshot comparison. Loose to survive minor rendering # differences across OS / GPU / driver versions. @@ -42,7 +42,7 @@ @pytest.fixture(autouse=True) def _enable_tutorial_test_mode(monkeypatch: pytest.MonkeyPatch) -> None: """Run tutorials against repo data/test through TestTools mode switching.""" - monkeypatch.setenv("PHYSIOMOTION_RUNNING_AS_TEST", "1") + monkeypatch.setenv("PHYSIOTWIN_RUNNING_AS_TEST", "1") def _compare_screenshots( @@ -236,14 +236,14 @@ def test_run(self, test_directories: dict[str, Path]) -> None: # ----------------------------------------------------------------------------- # Tutorials 8-10 - Cardiac mesh stage-prediction pipeline (bring-your-own-data) # -# These tutorials use a local ``D:/PhysioMotion4D/`` cardiac dataset and (for +# These tutorials use a local ``D:/PhysioTwin4D/`` cardiac dataset and (for # Tutorials 9 and 10) the optional PhysicsNeMo dependency, so they are skipped # automatically unless that data / those checkpoints are present. They produce # no screenshots; the tests assert the tutorial ran and populated # ``tutorial_results``. # ----------------------------------------------------------------------------- -_CARDIAC_DATA_ROOT = Path("D:/PhysioMotion4D") +_CARDIAC_DATA_ROOT = Path("D:/PhysioTwin4D") _CARDIAC_FITTED_MESHES_DIR = _CARDIAC_DATA_ROOT / "duke_data" / "fitted_kcl_meshes" _TUTORIALS_DIR = _REPO_ROOT / "tutorials" @@ -281,7 +281,7 @@ class TestTutorial08CardiacFitModel: def test_run(self) -> None: if not (_CARDIAC_DATA_ROOT / "duke_data" / "gated_nii").exists(): pytest.skip( - "Cardiac dataset not present at D:/PhysioMotion4D/. Tutorial 8 is " + "Cardiac dataset not present at D:/PhysioTwin4D/. Tutorial 8 is " "bring-your-own-data; see tutorials/README.md." ) results = _run_tutorial_script("tutorial_08_cardiac_fit_model.py") diff --git a/tests/test_usd_merge.py b/tests/test_usd_merge.py index 305fa08..c5ca33c 100644 --- a/tests/test_usd_merge.py +++ b/tests/test_usd_merge.py @@ -11,7 +11,7 @@ import pytest from pxr import Usd, UsdGeom, UsdShade -from physiomotion4d import USDTools +from physiotwin4d import USDTools def analyze_usd_file(filepath: str) -> dict[str, Any]: diff --git a/tests/test_usd_time_preservation.py b/tests/test_usd_time_preservation.py index 94a3042..0b13600 100644 --- a/tests/test_usd_time_preservation.py +++ b/tests/test_usd_time_preservation.py @@ -11,7 +11,7 @@ import pytest from pxr import Usd, UsdGeom -from physiomotion4d import USDTools +from physiotwin4d import USDTools def get_time_metadata(filepath: str) -> dict[str, Any]: diff --git a/tests/test_vtk_to_usd_library.py b/tests/test_vtk_to_usd_library.py index 717a5ce..ac0ab9a 100644 --- a/tests/test_vtk_to_usd_library.py +++ b/tests/test_vtk_to_usd_library.py @@ -2,7 +2,7 @@ """ Tests for VTK-to-USD conversion through ConvertVTKToUSD. -The low-level physiomotion4d.vtk_to_usd package is exercised only through +The low-level physiotwin4d.vtk_to_usd package is exercised only through ConvertVTKToUSD here. It remains a public advanced API, but repository tests should validate the supported application entry point. @@ -19,9 +19,9 @@ import pyvista as pv from pxr import Gf, Usd, UsdGeom, UsdShade -from physiomotion4d import ConvertVTKToUSD -from physiomotion4d.test_tools import TestTools -from physiomotion4d.usd_tools import USDTools +from physiotwin4d import ConvertVTKToUSD +from physiotwin4d.test_tools import TestTools +from physiotwin4d.usd_tools import USDTools def get_data_dir() -> Path: diff --git a/tests/test_workflow_convert_image_to_usd.py b/tests/test_workflow_convert_image_to_usd.py index 080e166..d7ede86 100644 --- a/tests/test_workflow_convert_image_to_usd.py +++ b/tests/test_workflow_convert_image_to_usd.py @@ -11,12 +11,12 @@ import pytest from pxr import Usd, UsdGeom -from physiomotion4d.register_images_base import RegisterImagesBase -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.register_images_base import RegisterImagesBase +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) -from physiomotion4d.workflow_convert_image_to_usd import WorkflowConvertImageToUSD +from physiotwin4d.workflow_convert_image_to_usd import WorkflowConvertImageToUSD def _small_image() -> itk.Image: diff --git a/tests/test_workflow_convert_image_to_vtk.py b/tests/test_workflow_convert_image_to_vtk.py index 58fbb0b..83d2455 100644 --- a/tests/test_workflow_convert_image_to_vtk.py +++ b/tests/test_workflow_convert_image_to_vtk.py @@ -6,9 +6,9 @@ import pytest -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware -from physiomotion4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK def test_default_segmentation_method_is_chest_total_segmentator() -> None: diff --git a/tests/test_workflow_fine_tune_icon_registration.py b/tests/test_workflow_fine_tune_icon_registration.py index 552ab9f..731e399 100644 --- a/tests/test_workflow_fine_tune_icon_registration.py +++ b/tests/test_workflow_fine_tune_icon_registration.py @@ -20,7 +20,7 @@ import pytest import yaml -from physiomotion4d.workflow_fine_tune_icon_registration import ( +from physiotwin4d.workflow_fine_tune_icon_registration import ( WorkflowFineTuneICONRegistration, ) diff --git a/tests/test_workflow_fit_statistical_model_to_patient.py b/tests/test_workflow_fit_statistical_model_to_patient.py index 9842f19..6bceea7 100644 --- a/tests/test_workflow_fit_statistical_model_to_patient.py +++ b/tests/test_workflow_fit_statistical_model_to_patient.py @@ -9,12 +9,12 @@ import numpy as np import pyvista as pv -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware -from physiomotion4d.segment_heart_simpleware_trimmed_branches import ( +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.segment_heart_simpleware_trimmed_branches import ( SegmentHeartSimplewareTrimmedBranches, ) -from physiomotion4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK -from physiomotion4d.workflow_fit_statistical_model_to_patient import ( +from physiotwin4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK +from physiotwin4d.workflow_fit_statistical_model_to_patient import ( WorkflowFitStatisticalModelToPatient, ) @@ -105,7 +105,7 @@ def process(self, **kwargs: Any) -> dict[str, Any]: return {"meshes": {"heart": heart_mesh}} monkeypatch.setattr( - "physiomotion4d.workflow_fit_statistical_model_to_patient." + "physiotwin4d.workflow_fit_statistical_model_to_patient." "WorkflowConvertImageToVTK", _FakeConvertImageToVTK, ) diff --git a/tests/test_workflow_reconstruct_highres_4d_ct.py b/tests/test_workflow_reconstruct_highres_4d_ct.py index 49ba28d..1eb36b6 100644 --- a/tests/test_workflow_reconstruct_highres_4d_ct.py +++ b/tests/test_workflow_reconstruct_highres_4d_ct.py @@ -7,10 +7,10 @@ import itk import pytest -from physiomotion4d.register_images_base import RegisterImagesBase -from physiomotion4d.register_images_greedy_icon import RegisterImagesGreedyICON -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.workflow_reconstruct_highres_4d_ct import ( +from physiotwin4d.register_images_base import RegisterImagesBase +from physiotwin4d.register_images_greedy_icon import RegisterImagesGreedyICON +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.workflow_reconstruct_highres_4d_ct import ( WorkflowReconstructHighres4DCT, ) diff --git a/tutorials/README.md b/tutorials/README.md index 656dd2c..2e77ec0 100644 --- a/tutorials/README.md +++ b/tutorials/README.md @@ -1,4 +1,4 @@ -# PhysioMotion4D Tutorials +# PhysioTwin4D Tutorials End-to-end Python scripts covering each major workflow in the library. These are the recommended starting point for new users. @@ -19,7 +19,7 @@ dataset licensing, and expected directory layout. | 4 | [tutorial_04_fit_statistical_model_to_patient.py](tutorial_04_fit_statistical_model_to_patient.py) | `WorkflowFitStatisticalModelToPatient` | KCL-Heart-Model plus Tutorial 3 output | | 5 | [tutorial_05_vtk_to_usd.py](tutorial_05_vtk_to_usd.py) | `WorkflowConvertVTKToUSD` | Output of tutorial 2 | | 6 | [tutorial_06_reconstruct_highres_4d_ct.py](tutorial_06_reconstruct_highres_4d_ct.py) | `WorkflowReconstructHighres4DCT` | DirLab-4DCT (manual) | -| 8 | [tutorial_08_cardiac_fit_model.py](tutorial_08_cardiac_fit_model.py) | `WorkflowFitStatisticalModelToPatient`, `WorkflowReconstructHighres4DCT` | Bring your own (cardiac gated CT, `D:/PhysioMotion4D/`) | +| 8 | [tutorial_08_cardiac_fit_model.py](tutorial_08_cardiac_fit_model.py) | `WorkflowFitStatisticalModelToPatient`, `WorkflowReconstructHighres4DCT` | Bring your own (cardiac gated CT, `D:/PhysioTwin4D/`) | | 9a | [tutorial_09a_cardiac_train_physicsnemo_mgn.py](tutorial_09a_cardiac_train_physicsnemo_mgn.py) | `physicsnemo.models.meshgraphnet.MeshGraphNet` (requires `[physicsnemo]` extra + `torch-geometric`) | Tutorial 8 output | | 9b | [tutorial_09b_cardiac_train_physicsnemo_mlp.py](tutorial_09b_cardiac_train_physicsnemo_mlp.py) | `physicsnemo.models.mlp.FullyConnected` (requires `[physicsnemo]` extra) | Tutorial 8 output | | 10a | [tutorial_10a_cardiac_eval_physicsnemo_mgn.py](tutorial_10a_cardiac_eval_physicsnemo_mgn.py) | `physicsnemo.models.meshgraphnet.MeshGraphNet` (requires `[physicsnemo]` extra + `torch-geometric`) | Tutorial 9a checkpoint | @@ -27,7 +27,7 @@ dataset licensing, and expected directory layout. > **Tutorials 8-10 are bring-your-own-data.** Unlike Tutorials 1-6, they do not > use the repository `data/` directory or a downloadable sample. Their path -> constants point at a local `D:/PhysioMotion4D/` cardiac layout (gated CT, +> constants point at a local `D:/PhysioTwin4D/` cardiac layout (gated CT, > labelmaps, the KCL volume PCA model, and ICON weights); edit those constants to > match your own data. (The former DirLab lung-lobe PCA tutorial, number 7, has > been removed; the numbering continues at 8.) @@ -54,7 +54,7 @@ the cells in order with **Run Cell**). The script's `if __name__ == To use different paths, edit the constants near the top of the tutorial script. For repeatable command-line execution with path arguments, use the -installed `physiomotion4d-*` CLI commands instead. +installed `physiotwin4d-*` CLI commands instead. ## Running as Pytest Tutorial Tests @@ -84,7 +84,7 @@ The cardiac mesh stage-prediction pipeline (Tutorials 8 -> 9 -> 10) is bring-your-own-data and runs in order: 6. **Tutorial 8** fits the KCL cardiac PCA model to each patient's reference CT and propagates the fitted SSM mesh through every gated phase (output feeds Tutorial 9). -7. **Tutorial 9a / 9b** train a PhysicsNeMo MeshGraphNet (9a) and MLP (9b) to predict a cardiac surface at any cardiac stage. PhysicsNeMo is an optional extra: install with `pip install "physiomotion4d[physicsnemo]"` (requires Python >= 3.11); the MeshGraphNet also needs `torch-geometric`. +7. **Tutorial 9a / 9b** train a PhysicsNeMo MeshGraphNet (9a) and MLP (9b) to predict a cardiac surface at any cardiac stage. PhysicsNeMo is an optional extra: install with `pip install "physiotwin4d[physicsnemo]"` (requires Python >= 3.11); the MeshGraphNet also needs `torch-geometric`. 8. **Tutorial 10a / 10b** load a trained MeshGraphNet (10a) or MLP (10b) checkpoint and predict / score cardiac surfaces for one subject. Each can be run from the command line or, with no arguments, via its `run_tutorial` entry point. ## For Contributors diff --git a/tutorials/tutorial_01_heart_gated_ct_to_usd.py b/tutorials/tutorial_01_heart_gated_ct_to_usd.py index 2f20c39..eba2bd3 100644 --- a/tutorials/tutorial_01_heart_gated_ct_to_usd.py +++ b/tutorials/tutorial_01_heart_gated_ct_to_usd.py @@ -75,9 +75,9 @@ import itk -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_convert_image_to_usd import ( +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_convert_image_to_usd import ( WorkflowConvertImageToUSD, ) diff --git a/tutorials/tutorial_02_ct_to_vtk.py b/tutorials/tutorial_02_ct_to_vtk.py index 6226942..571efdf 100644 --- a/tutorials/tutorial_02_ct_to_vtk.py +++ b/tutorials/tutorial_02_ct_to_vtk.py @@ -23,12 +23,12 @@ import itk import pyvista as pv -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_convert_image_to_vtk import WorkflowConvertImageToVTK # nnUNetv2 (used by TotalSegmentator inside several workflows) spawns a # multiprocessing.Pool. On Windows the spawn start method re-imports this diff --git a/tutorials/tutorial_03_create_statistical_model.py b/tutorials/tutorial_03_create_statistical_model.py index 22eb6d1..9726f80 100644 --- a/tutorials/tutorial_03_create_statistical_model.py +++ b/tutorials/tutorial_03_create_statistical_model.py @@ -24,8 +24,8 @@ import numpy as np import pyvista as pv -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_create_statistical_model import ( +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_create_statistical_model import ( WorkflowCreateStatisticalModel, ) diff --git a/tutorials/tutorial_04_fit_statistical_model_to_patient.py b/tutorials/tutorial_04_fit_statistical_model_to_patient.py index ae96b47..2743091 100644 --- a/tutorials/tutorial_04_fit_statistical_model_to_patient.py +++ b/tutorials/tutorial_04_fit_statistical_model_to_patient.py @@ -24,8 +24,8 @@ import pyvista as pv -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_fit_statistical_model_to_patient import ( +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_fit_statistical_model_to_patient import ( WorkflowFitStatisticalModelToPatient, ) diff --git a/tutorials/tutorial_05_vtk_to_usd.py b/tutorials/tutorial_05_vtk_to_usd.py index 7676d47..70a3b9e 100644 --- a/tutorials/tutorial_05_vtk_to_usd.py +++ b/tutorials/tutorial_05_vtk_to_usd.py @@ -20,8 +20,8 @@ from pathlib import Path from typing import Optional -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD # nnUNetv2 (used by TotalSegmentator inside several workflows) spawns a # multiprocessing.Pool. On Windows the spawn start method re-imports this diff --git a/tutorials/tutorial_06_reconstruct_highres_4d_ct.py b/tutorials/tutorial_06_reconstruct_highres_4d_ct.py index 91c8566..1d88f65 100644 --- a/tutorials/tutorial_06_reconstruct_highres_4d_ct.py +++ b/tutorials/tutorial_06_reconstruct_highres_4d_ct.py @@ -23,9 +23,9 @@ import itk -from physiomotion4d.register_images_greedy_icon import RegisterImagesGreedyICON -from physiomotion4d.test_tools import TestTools -from physiomotion4d.workflow_reconstruct_highres_4d_ct import ( +from physiotwin4d.register_images_greedy_icon import RegisterImagesGreedyICON +from physiotwin4d.test_tools import TestTools +from physiotwin4d.workflow_reconstruct_highres_4d_ct import ( WorkflowReconstructHighres4DCT, ) diff --git a/tutorials/tutorial_08_cardiac_fit_model.py b/tutorials/tutorial_08_cardiac_fit_model.py index f2e421a..4732265 100644 --- a/tutorials/tutorial_08_cardiac_fit_model.py +++ b/tutorials/tutorial_08_cardiac_fit_model.py @@ -27,14 +27,14 @@ ------------------- This is a bring-your-own-data tutorial. Unlike Tutorials 1-6, it does not use the repository ``data/`` directory or a downloadable sample; the path constants below -point at a local ``D:/PhysioMotion4D/`` layout. Edit them to match your own data. +point at a local ``D:/PhysioTwin4D/`` layout. Edit them to match your own data. Data Required ------------- - * ``D:/PhysioMotion4D/duke_data/gated_nii/pm00??/`` - gated NIfTI CT per patient - * ``D:/PhysioMotion4D/duke_data/simple_ascardio/pm00??/`` - matching labelmaps - * ``D:/PhysioMotion4D/kcl-heart-pca/pca-vol-kcl/`` - PCA model (pca_mean.vtu, pca_model.json) - * ``D:/PhysioMotion4D/duke_data/icon_registration/`` - ICON registration weights + * ``D:/PhysioTwin4D/duke_data/gated_nii/pm00??/`` - gated NIfTI CT per patient + * ``D:/PhysioTwin4D/duke_data/simple_ascardio/pm00??/`` - matching labelmaps + * ``D:/PhysioTwin4D/kcl-heart-pca/pca-vol-kcl/`` - PCA model (pca_mean.vtu, pca_model.json) + * ``D:/PhysioTwin4D/duke_data/icon_registration/`` - ICON registration weights Outputs (per patient, under ``OUTPUT_DIR/pm00??/``) --------------------------------------------------- @@ -58,14 +58,14 @@ import itk import pyvista as pv -from physiomotion4d import ( +from physiotwin4d import ( ContourTools, RegisterImagesICON, TransformTools, WorkflowFitStatisticalModelToPatient, WorkflowReconstructHighres4DCT, ) -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # nnUNetv2 (used by TotalSegmentator inside several workflows) spawns a # multiprocessing.Pool. On Windows the spawn start method re-imports this @@ -75,19 +75,16 @@ if __name__ == "__main__": # %% # Path configuration (bring-your-own-data: edit for your local layout) - DATA_DIR = Path("D:/PhysioMotion4D/duke_data/gated_nii") - LABELMAP_DIR = Path("D:/PhysioMotion4D/duke_data/simple_ascardio") - SSM_MEAN_MESH_FILE = Path( - "D:/PhysioMotion4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu" - ) - SSM_MODEL_FILE = Path("D:/PhysioMotion4D/kcl-heart-pca/pca-vol-kcl/pca_model.json") + DATA_DIR = Path("D:/PhysioTwin4D/duke_data/gated_nii") + LABELMAP_DIR = Path("D:/PhysioTwin4D/duke_data/simple_ascardio") + SSM_MEAN_MESH_FILE = Path("D:/PhysioTwin4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu") + SSM_MODEL_FILE = Path("D:/PhysioTwin4D/kcl-heart-pca/pca-vol-kcl/pca_model.json") ICON_WEIGHTS_PATH = Path( - "D:/PhysioMotion4D/duke_data/icon_registration/" - "icon_ct_cardiac_gated_weights.trch" + "D:/PhysioTwin4D/duke_data/icon_registration/icon_ct_cardiac_gated_weights.trch" ) # All outputs (fitted meshes, transforms, warped labelmaps) are written here; # this is also the directory the Tutorial 9 trainers read from. - OUTPUT_DIR = Path("D:/PhysioMotion4D/duke_data/fitted_kcl_meshes") + OUTPUT_DIR = Path("D:/PhysioTwin4D/duke_data/fitted_kcl_meshes") # Simpleware's heart interior chamber labels, excluded from the distance map. LABELMAP_INTERIOR_OBJECT_IDS = [1, 2, 3, 4] # Recompute the expensive fit/registration steps (True) or reload cached diff --git a/tutorials/tutorial_09a_cardiac_train_physicsnemo_mgn.py b/tutorials/tutorial_09a_cardiac_train_physicsnemo_mgn.py index 9885c5c..4cba7a8 100644 --- a/tutorials/tutorial_09a_cardiac_train_physicsnemo_mgn.py +++ b/tutorials/tutorial_09a_cardiac_train_physicsnemo_mgn.py @@ -34,7 +34,7 @@ Bring Your Own Data ------------------- This is a bring-your-own-data tutorial: the path constants below point at a local -``D:/PhysioMotion4D/`` layout produced by Tutorial 8, not at the repository +``D:/PhysioTwin4D/`` layout produced by Tutorial 8, not at the repository ``data/`` directory. Edit them to match your own data location. Data Required @@ -46,7 +46,7 @@ ---------------------- PhysicsNeMo and PyTorch Geometric must be installed:: - pip install "physiomotion4d[physicsnemo]" + pip install "physiotwin4d[physicsnemo]" pip install torch-geometric ``torch_scatter`` (a PyTorch Geometric backend) must be built from source when using a @@ -71,7 +71,7 @@ import pyvista as pv import torch -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools try: import torch_geometric.utils as pyg_utils @@ -81,7 +81,7 @@ except ImportError as exc: raise ImportError( "Tutorial 9a requires PhysicsNeMo and PyTorch Geometric. Install with:\n" - ' pip install "physiomotion4d[physicsnemo]"\n' + ' pip install "physiotwin4d[physicsnemo]"\n' " pip install torch-geometric" ) from exc @@ -89,8 +89,8 @@ if __name__ == "__main__": # %% TUTORIALS_DIR = Path(__file__).resolve().parent - FITTED_MESHES_DIR = Path("D:/PhysioMotion4D/duke_data/fitted_kcl_meshes") - PCA_MEAN_VTU = Path("D:/PhysioMotion4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu") + FITTED_MESHES_DIR = Path("D:/PhysioTwin4D/duke_data/fitted_kcl_meshes") + PCA_MEAN_VTU = Path("D:/PhysioTwin4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu") EPOCHS = 1500 OUTPUT_DIR = TUTORIALS_DIR / "output_mgn" RMSE_LOG_INTERVAL = 100 diff --git a/tutorials/tutorial_09b_cardiac_train_physicsnemo_mlp.py b/tutorials/tutorial_09b_cardiac_train_physicsnemo_mlp.py index 2e3c366..cc97616 100644 --- a/tutorials/tutorial_09b_cardiac_train_physicsnemo_mlp.py +++ b/tutorials/tutorial_09b_cardiac_train_physicsnemo_mlp.py @@ -21,13 +21,13 @@ Bring Your Own Data ------------------- This is a bring-your-own-data tutorial: the path constants below point at a local -``D:/PhysioMotion4D/`` layout produced by Tutorial 8, not at the repository +``D:/PhysioTwin4D/`` layout produced by Tutorial 8, not at the repository ``data/`` directory. Edit them to match your own data location. Data Required ------------- Run Tutorial 8 first so -``D:/PhysioMotion4D/duke_data/fitted_kcl_meshes/pm00??/`` contains: +``D:/PhysioTwin4D/duke_data/fitted_kcl_meshes/pm00??/`` contains: * ``pm00XX_ssm_surface.vtp`` - reference (template) SSM surface * ``pm00XX_ssm_pca_coefficients.json`` - fitted PCA coefficient vector @@ -44,9 +44,9 @@ Extra Install Required ---------------------- -PhysicsNeMo is an optional dependency of PhysioMotion4D. Install it with:: +PhysicsNeMo is an optional dependency of PhysioTwin4D. Install it with:: - pip install "physiomotion4d[physicsnemo]" + pip install "physiotwin4d[physicsnemo]" PhysicsNeMo itself requires Python >= 3.11. """ @@ -68,14 +68,14 @@ import torch -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools try: from physicsnemo.models.mlp import FullyConnected except ImportError as exc: # pragma: no cover - import-time guard raise ImportError( "Tutorial 9b requires PhysicsNeMo, which is an optional dependency. " - 'Install with: pip install "physiomotion4d[physicsnemo]" ' + 'Install with: pip install "physiotwin4d[physicsnemo]" ' "(requires Python >= 3.11).", ) from exc @@ -89,8 +89,8 @@ if __name__ == "__main__": # %% TUTORIALS_DIR = Path(__file__).resolve().parent - FITTED_MESHES_DIR = Path("D:/PhysioMotion4D/duke_data/fitted_kcl_meshes") - PCA_MEAN_VTU = Path("D:/PhysioMotion4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu") + FITTED_MESHES_DIR = Path("D:/PhysioTwin4D/duke_data/fitted_kcl_meshes") + PCA_MEAN_VTU = Path("D:/PhysioTwin4D/kcl-heart-pca/pca-vol-kcl/pca_mean.vtu") EPOCHS = 10000 OUTPUT_DIR = TUTORIALS_DIR / "output" RMSE_LOG_INTERVAL = ( diff --git a/tutorials/tutorial_10a_cardiac_eval_physicsnemo_mgn.py b/tutorials/tutorial_10a_cardiac_eval_physicsnemo_mgn.py index b0ba8d5..32093ac 100644 --- a/tutorials/tutorial_10a_cardiac_eval_physicsnemo_mgn.py +++ b/tutorials/tutorial_10a_cardiac_eval_physicsnemo_mgn.py @@ -10,7 +10,7 @@ ``DEFAULT_SUBJECT`` / ``DEFAULT_EPOCH`` constants below). This is a bring-your-own-data tutorial: the path constants below point at a local -``D:/PhysioMotion4D/`` layout and the Tutorial 9a run directory, not at the +``D:/PhysioTwin4D/`` layout and the Tutorial 9a run directory, not at the repository ``data/`` directory. Usage (command line) @@ -55,14 +55,14 @@ except ImportError as exc: raise ImportError( "Requires PhysicsNeMo and PyTorch Geometric. Install with:\n" - ' pip install "physiomotion4d[physicsnemo]"\n' + ' pip install "physiotwin4d[physicsnemo]"\n' " pip install torch-geometric" ) from exc logger = logging.getLogger("tutorial_10a_cardiac_eval_physicsnemo_mgn") TUTORIALS_DIR = Path(__file__).resolve().parent -FITTED_MESHES_DIR = Path("D:/PhysioMotion4D/duke_data/fitted_kcl_meshes") +FITTED_MESHES_DIR = Path("D:/PhysioTwin4D/duke_data/fitted_kcl_meshes") # Tutorial 9a run directory to evaluate (matches that trainer's OUTPUT_DIR). OUTPUT_DIR = TUTORIALS_DIR / "output_mgn" diff --git a/tutorials/tutorial_10b_cardiac_eval_physicsnemo_mlp.py b/tutorials/tutorial_10b_cardiac_eval_physicsnemo_mlp.py index d3c9bb6..e006d5d 100644 --- a/tutorials/tutorial_10b_cardiac_eval_physicsnemo_mlp.py +++ b/tutorials/tutorial_10b_cardiac_eval_physicsnemo_mlp.py @@ -10,7 +10,7 @@ ``DEFAULT_SUBJECT`` / ``DEFAULT_EPOCH`` constants below). This is a bring-your-own-data tutorial: the path constants below point at a local -``D:/PhysioMotion4D/`` layout and the Tutorial 9b run directory, not at the +``D:/PhysioTwin4D/`` layout and the Tutorial 9b run directory, not at the repository ``data/`` directory. Usage (command line) @@ -66,13 +66,13 @@ from physicsnemo.models.mlp import FullyConnected except ImportError as exc: raise ImportError( - 'Requires PhysicsNeMo. Install with: pip install "physiomotion4d[physicsnemo]"' + 'Requires PhysicsNeMo. Install with: pip install "physiotwin4d[physicsnemo]"' ) from exc logger = logging.getLogger("tutorial_10b_cardiac_eval_physicsnemo_mlp") TUTORIALS_DIR = Path(__file__).resolve().parent -FITTED_MESHES_DIR = Path("D:/PhysioMotion4D/duke_data/fitted_kcl_meshes") +FITTED_MESHES_DIR = Path("D:/PhysioTwin4D/duke_data/fitted_kcl_meshes") # Tutorial 9b run directory to evaluate (matches that trainer's OUTPUT_DIR). OUTPUT_DIR = TUTORIALS_DIR / "output" BATCH_SIZE = 262144 From 7002fb25f81accd34e8e34baf74d3d7e8a8a9478 Mon Sep 17 00:00:00 2001 From: Stephen Aylward Date: Mon, 6 Jul 2026 22:30:03 -0400 Subject: [PATCH 2/2] Rename PhysioMotion4D to PhysioTwin4D across docs, tutorials, experiments, and infra Bulk text substitution across docs/, experiments/, utils/, .agents/, .github/, .cursor/, data/, and root files (README, AGENTS.md, CLAUDE.md, MANIFEST.in, statistics.md, .readthedocs.yaml). Also renames the internal pm4d abbreviation to pt4d (Sphinx template placeholder and custom.css classes/variables), regenerates docs/API_MAP.md, and bumps the stale 2026.05.07 version references in README.md, docs/changelog.rst, and docs/PYPI_RELEASE_GUIDE.md to 2026.07.0. Co-Authored-By: Claude Sonnet 5 --- .agents/agents/architecture.md | 12 +- .agents/agents/docs.md | 6 +- .agents/agents/implementation.md | 12 +- .agents/agents/testing.md | 8 +- .agents/skills/check-conventions/SKILL.md | 14 +-- .agents/skills/commit/SKILL.md | 2 +- .agents/skills/doc-feature/SKILL.md | 4 +- .agents/skills/impl/SKILL.md | 4 +- .agents/skills/plan/SKILL.md | 4 +- .agents/skills/regen-api-map/SKILL.md | 4 +- .agents/skills/test-feature/SKILL.md | 4 +- .cursor/rules/project-standards.mdc | 4 +- .github/scripts/build_dashboard.py | 20 ++-- .github/workflows/README.md | 2 +- .github/workflows/ci.yml | 20 ++-- .github/workflows/nightly-health.yml | 8 +- .github/workflows/test-slow.yml | 6 +- .readthedocs.yaml | 2 +- AGENTS.md | 12 +- CLAUDE.md | 6 +- MANIFEST.in | 8 +- README.md | 98 ++++++++-------- data/KCL-Heart-Model/README.md | 2 +- data/README.md | 10 +- data/Slicer-Heart-CT/download_and_convert.py | 4 +- docs/PYPI_RELEASE_GUIDE.md | 46 ++++---- docs/README.md | 4 +- docs/_static/custom.css | 110 +++++++++--------- docs/api/base.rst | 18 +-- docs/api/cli/convert_image_to_usd.rst | 2 +- docs/api/cli/convert_image_to_vtk.rst | 2 +- docs/api/cli/convert_vtk_to_usd.rst | 2 +- docs/api/cli/create_statistical_model.rst | 2 +- docs/api/cli/download_data.rst | 2 +- .../cli/fit_statistical_model_to_patient.rst | 2 +- docs/api/cli/index.rst | 8 +- docs/api/cli/reconstruct_highres_4d_ct.rst | 2 +- docs/api/cli/visualize_pca_modes.rst | 2 +- docs/api/index.rst | 40 +++---- docs/api/model_registration/distance_maps.rst | 4 +- docs/api/model_registration/icp.rst | 4 +- docs/api/model_registration/icp_itk.rst | 4 +- docs/api/model_registration/index.rst | 4 +- docs/api/model_registration/pca.rst | 4 +- docs/api/registration/ants.rst | 6 +- docs/api/registration/base.rst | 4 +- docs/api/registration/greedy.rst | 6 +- docs/api/registration/icon.rst | 6 +- docs/api/registration/index.rst | 6 +- docs/api/registration/time_series.rst | 6 +- docs/api/segmentation/base.rst | 10 +- docs/api/segmentation/index.rst | 6 +- docs/api/segmentation/simpleware.rst | 6 +- docs/api/segmentation/totalsegmentator.rst | 12 +- docs/api/usd/anatomy_tools.rst | 4 +- docs/api/usd/index.rst | 6 +- docs/api/usd/tools.rst | 4 +- docs/api/usd/vtk_conversion.rst | 4 +- docs/api/usd/vtk_to_usd_lib.rst | 24 ++-- docs/api/utilities/contour_tools.rst | 4 +- docs/api/utilities/data_download.rst | 4 +- docs/api/utilities/image_conversion.rst | 4 +- docs/api/utilities/image_tools.rst | 4 +- docs/api/utilities/index.rst | 2 +- docs/api/utilities/labelmap_tools.rst | 4 +- docs/api/utilities/test_tools.rst | 6 +- docs/api/utilities/transform_tools.rst | 4 +- docs/api/workflows.rst | 28 ++--- docs/architecture.rst | 22 ++-- docs/changelog.rst | 9 +- docs/cli_scripts/4dct_reconstruction.rst | 12 +- docs/cli_scripts/best_practices.rst | 16 +-- docs/cli_scripts/brain_vessel_modeling.rst | 2 +- docs/cli_scripts/byod_tutorials.rst | 68 +++++------ docs/cli_scripts/create_statistical_model.rst | 18 +-- docs/cli_scripts/download_data.rst | 14 +-- .../fit_statistical_model_to_patient.rst | 16 +-- docs/cli_scripts/heart_gated_ct.rst | 18 +-- docs/cli_scripts/lung_gated_ct.rst | 4 +- docs/cli_scripts/overview.rst | 32 ++--- docs/cli_scripts/vtk_to_usd.rst | 18 +-- docs/conf.py | 6 +- docs/contributing.rst | 26 ++--- docs/developer/architecture.rst | 4 +- docs/developer/core.rst | 8 +- docs/developer/extending.rst | 8 +- docs/developer/registration_images.rst | 10 +- docs/developer/registration_models.rst | 12 +- docs/developer/segmentation.rst | 14 +-- docs/developer/transform_conventions.rst | 16 +-- docs/developer/usd_generation.rst | 28 ++--- docs/developer/utilities.rst | 12 +- docs/developer/workflows.rst | 28 ++--- docs/examples.rst | 42 +++---- docs/faq.rst | 14 +-- docs/index.rst | 106 ++++++++--------- docs/installation.rst | 50 ++++---- docs/isaac_for_healthcare.rst | 12 +- docs/quickstart.rst | 40 +++---- docs/references.rst | 10 +- docs/troubleshooting.rst | 16 +-- docs/tutorials.rst | 70 +++++------ .../colormap_vtk_to_usd.py | 4 +- .../convert_chop_alterra_valve_to_usd.py | 6 +- .../convert_chop_heart_vtk_to_usd.py | 2 +- .../convert_chop_tpv25_valve_to_usd.py | 6 +- .../convert_vtk_to_usd_using_class.py | 2 +- .../1-input_meshes_to_input_surfaces.py | 2 +- .../2-input_surfaces_to_surfaces_aligned.py | 6 +- .../3-registration_based_correspondence.py | 6 +- ...rfaces_aligned_correspond_to_pca_inputs.py | 4 +- .../5-compute_pca_model.py | 2 +- .../Heart-Create_Statistical_Model/README.md | 14 +-- .../0-cardiacGatedCT_segment_and_landmark.py | 12 +- .../1-initial_registration.py | 18 +-- .../2-finetune_icon.py | 14 +-- .../3-eval_icon.py | 12 +- .../registration_test.py | 10 +- .../setup.sh | 2 +- .../0-download_and_convert_4d_to_3d.py | 4 +- .../Heart-GatedCT_To_USD/1-register_images.py | 8 +- .../2-generate_segmentation.py | 6 +- ...3-transform_dynamic_and_static_contours.py | 10 +- .../4-merge_dynamic_and_static_usd.py | 2 +- .../Heart-Simpleware_Segmentation/README.md | 26 ++--- .../simpleware_heart_segmentation.py | 8 +- .../heart_model_to_model_icp_itk.py | 8 +- .../heart_model_to_model_registration_pca.py | 8 +- .../heart_model_to_patient-CHOPValve.py | 6 +- .../heart_model_to_patient.py | 6 +- .../0-download_and_convert_4d_to_3d.py | 4 +- .../1-heart_vtkseries_to_usd.py | 6 +- .../0-register_dirlab_4dct.py | 8 +- .../1-make_dirlab_models.py | 6 +- .../2-paint_dirlab_models.py | 4 +- .../Experiment_ArrangeOnStage.py | 2 +- .../Experiment_CombineModels.py | 2 +- .../Lung-GatedCT_To_USD/Experiment_SegReg.py | 4 +- experiments/Lung-VesselsAirways/0-GenData.py | 2 +- experiments/README.md | 38 +++--- .../Reconstruct4DCT/reconstruct_4d_ct.py | 2 +- .../reconstruct_4d_ct_class.py | 4 +- statistics.md | 12 +- utils/ai_agent_github_reviews.py | 6 +- utils/generate_api_map.py | 2 +- 145 files changed, 906 insertions(+), 899 deletions(-) diff --git a/.agents/agents/architecture.md b/.agents/agents/architecture.md index 1411561..97125d0 100644 --- a/.agents/agents/architecture.md +++ b/.agents/agents/architecture.md @@ -1,17 +1,17 @@ --- -name: PhysioMotion4D Architecture Agent -description: Analyzes the PhysioMotion4D codebase and produces numbered design plans with trade-offs. Does not write implementation code. Flags coordinate-system and ITK/PyVista boundary risks. +name: PhysioTwin4D Architecture Agent +description: Analyzes the PhysioTwin4D codebase and produces numbered design plans with trade-offs. Does not write implementation code. Flags coordinate-system and ITK/PyVista boundary risks. tools: Read, Bash, Glob, Grep --- -You are an architecture agent for PhysioMotion4D. Analyze the codebase and produce +You are an architecture agent for PhysioTwin4D. Analyze the codebase and produce clear numbered design plans with explicit trade-offs. Do not write implementation code. ## Codebase map ```text -src/physiomotion4d/ - physiomotion4d_base.py — base class with shared logger +src/physiotwin4d/ + physiotwin4d_base.py — base class with shared logger segment_anatomy_base.py — abstract segmentation interface segment_chest_*.py — TotalSegmentator, VISTA-3D, NIM, Ensemble register_images_*.py — ICON, ANTs, Greedy, time-series wrappers @@ -27,7 +27,7 @@ Use `docs/API_MAP.md` to locate classes and signatures without manual searching. ## Design invariants to preserve -- `PhysioMotion4DBase` inheritance for runtime workflow / segmentation / +- `PhysioTwin4DBase` inheritance for runtime workflow / segmentation / registration / USD classes. Helper, data-container, and standalone-script classes do not inherit. - Segmenters return anatomy group masks with consistent label IDs. diff --git a/.agents/agents/docs.md b/.agents/agents/docs.md index 5e43302..082352b 100644 --- a/.agents/agents/docs.md +++ b/.agents/agents/docs.md @@ -1,10 +1,10 @@ --- -name: PhysioMotion4D Docs Agent -description: Updates docstrings, inline comments, and docs/API_MAP.md for PhysioMotion4D. Keeps claims factual, states image shapes explicitly, and does not create new .md files. +name: PhysioTwin4D Docs Agent +description: Updates docstrings, inline comments, and docs/API_MAP.md for PhysioTwin4D. Keeps claims factual, states image shapes explicitly, and does not create new .md files. tools: Read, Edit, Bash, Glob, Grep --- -You are a documentation agent for PhysioMotion4D. Keep docstrings, type annotations, +You are a documentation agent for PhysioTwin4D. Keep docstrings, type annotations, and the API map accurate and concise. ## Scope diff --git a/.agents/agents/implementation.md b/.agents/agents/implementation.md index 2465c75..b9d7b21 100644 --- a/.agents/agents/implementation.md +++ b/.agents/agents/implementation.md @@ -1,17 +1,17 @@ --- -name: PhysioMotion4D Implementation Agent -description: Implements features, bug fixes, or refactors in PhysioMotion4D. Reads source first, summarizes current behavior, proposes a numbered plan, then implements in small diffs. Calls out breaking changes. +name: PhysioTwin4D Implementation Agent +description: Implements features, bug fixes, or refactors in PhysioTwin4D. Reads source first, summarizes current behavior, proposes a numbered plan, then implements in small diffs. Calls out breaking changes. tools: Read, Edit, Write, Bash, Glob, Grep --- -You are an implementation agent for PhysioMotion4D, an early-alpha scientific Python library +You are an implementation agent for PhysioTwin4D, an early-alpha scientific Python library that converts 4D CT scans into animated USD models for NVIDIA Omniverse. ## Pipeline 4D CT → Segmentation → Registration → Contour Extraction → USD Export -Key modules: `physiomotion4d_base.py`, `segment_chest_*.py`, `register_images_*.py`, +Key modules: `physiotwin4d_base.py`, `segment_chest_*.py`, `register_images_*.py`, `register_models_*.py`, `contour_tools.py`, `convert_vtk_to_usd.py`, `vtk_to_usd/`, `workflow_*.py`. Use `docs/API_MAP.md` to locate classes before searching manually. @@ -27,9 +27,9 @@ Key modules: `physiomotion4d_base.py`, `segment_chest_*.py`, `register_images_*. ## Code rules - Runtime workflow / segmentation / registration / USD classes inherit from - `PhysioMotion4DBase`. Standalone scripts, data containers, and helper + `PhysioTwin4DBase`. Standalone scripts, data containers, and helper classes do not. -- In `PhysioMotion4DBase` subclasses use `self.log_info()` / `self.log_debug()`, +- In `PhysioTwin4DBase` subclasses use `self.log_info()` / `self.log_debug()`, never `print()`. Standalone scripts may use `print()`. - No emojis in `.py` files. Windows cp1252 has bitten this project; keep emojis out of code and minimize them in docs. diff --git a/.agents/agents/testing.md b/.agents/agents/testing.md index 38158a7..3b4ad82 100644 --- a/.agents/agents/testing.md +++ b/.agents/agents/testing.md @@ -1,10 +1,10 @@ --- -name: PhysioMotion4D Testing Agent -description: Writes and updates pytest tests for PhysioMotion4D. Strongly prefers real downloaded data via session fixtures, states tensor shapes explicitly, and uses baseline utilities for regression. +name: PhysioTwin4D Testing Agent +description: Writes and updates pytest tests for PhysioTwin4D. Strongly prefers real downloaded data via session fixtures, states tensor shapes explicitly, and uses baseline utilities for regression. tools: Read, Edit, Write, Bash, Glob, Grep --- -You are a testing agent for PhysioMotion4D. Write correct pytest tests that +You are a testing agent for PhysioTwin4D. Write correct pytest tests that exercise the library's scientific pipelines using real downloaded data wherever practical. @@ -12,7 +12,7 @@ wherever practical. - `tests/conftest.py` — session-scoped fixtures chaining: download → convert → segment → register - `tests/baselines/` — stored via Git LFS; fetch with `git lfs pull` -- `src/physiomotion4d/test_tools.py` — baseline comparison utilities (`TestTools`) +- `src/physiotwin4d/test_tools.py` — baseline comparison utilities (`TestTools`) - Markers (all opt-in via `--run-`): `slow`, `requires_gpu`, `requires_simpleware`, `experiment`, `tutorial`. The `requires_data` marker no longer exists — tests that need downloadable data pull it through the diff --git a/.agents/skills/check-conventions/SKILL.md b/.agents/skills/check-conventions/SKILL.md index f7b788b..0c69145 100644 --- a/.agents/skills/check-conventions/SKILL.md +++ b/.agents/skills/check-conventions/SKILL.md @@ -1,8 +1,8 @@ --- -description: Audit changed files (or a given path) against PhysioMotion4D's hard project rules — base-class inheritance, logging, coordinate conventions, USD entry point, Windows multiprocessing guard, quoting, type-hint style, line length, and emoji ban. Reports violations without auto-fixing. +description: Audit changed files (or a given path) against PhysioTwin4D's hard project rules — base-class inheritance, logging, coordinate conventions, USD entry point, Windows multiprocessing guard, quoting, type-hint style, line length, and emoji ban. Reports violations without auto-fixing. --- -Audit PhysioMotion4D source for hard-rule violations. +Audit PhysioTwin4D source for hard-rule violations. $ARGUMENTS @@ -26,15 +26,15 @@ context such as class inheritance), then flag every occurrence of: ### Base class and logging - [ ] A class that orchestrates workflow / segmentation / registration / USD - conversion but does **not** inherit from `PhysioMotion4DBase`. + conversion but does **not** inherit from `PhysioTwin4DBase`. - [ ] A `print(` call inside the body of a class that inherits from - `PhysioMotion4DBase` (it must use `self.log_info()` / `self.log_debug()`). + `PhysioTwin4DBase` (it must use `self.log_info()` / `self.log_debug()`). Standalone scripts and helper / data-container classes may use `print()`. ### USD / coordinate conventions -- [ ] An `import` of `physiomotion4d.vtk_to_usd` (or `from ... vtk_to_usd ...`) - from a file that is **not** `src/physiomotion4d/convert_vtk_to_usd.py` - and is **not** itself inside `src/physiomotion4d/vtk_to_usd/`. +- [ ] An `import` of `physiotwin4d.vtk_to_usd` (or `from ... vtk_to_usd ...`) + from a file that is **not** `src/physiotwin4d/convert_vtk_to_usd.py` + and is **not** itself inside `src/physiotwin4d/vtk_to_usd/`. Experiments, CLIs, tests, and tutorials must use `ConvertVTKToUSD`. - [ ] A docstring or comment claiming PyVista surfaces are in **RAS** — they are in **LPS** internally; convert to USD Y-up only at export. diff --git a/.agents/skills/commit/SKILL.md b/.agents/skills/commit/SKILL.md index 87910b9..6a940c8 100644 --- a/.agents/skills/commit/SKILL.md +++ b/.agents/skills/commit/SKILL.md @@ -2,7 +2,7 @@ description: Stage all tracked modifications and deletions, draft a commit message from the diff, fix any pre-commit hook failures, and repeat until the commit succeeds. --- -Commit all tracked pending changes in the PhysioMotion4D repository +Commit all tracked pending changes in the PhysioTwin4D repository (equivalent to `git commit -a`, excluding new untracked files). $ARGUMENTS diff --git a/.agents/skills/doc-feature/SKILL.md b/.agents/skills/doc-feature/SKILL.md index 874055c..d23e42d 100644 --- a/.agents/skills/doc-feature/SKILL.md +++ b/.agents/skills/doc-feature/SKILL.md @@ -1,8 +1,8 @@ --- -description: Inspect changed PhysioMotion4D code and existing docstrings, update docstrings and inline comments with accurate shape/axis information, and regenerate docs/API_MAP.md if public APIs changed. +description: Inspect changed PhysioTwin4D code and existing docstrings, update docstrings and inline comments with accurate shape/axis information, and regenerate docs/API_MAP.md if public APIs changed. --- -Update documentation for the following in PhysioMotion4D: +Update documentation for the following in PhysioTwin4D: $ARGUMENTS diff --git a/.agents/skills/impl/SKILL.md b/.agents/skills/impl/SKILL.md index 9fef992..e7f5ea1 100644 --- a/.agents/skills/impl/SKILL.md +++ b/.agents/skills/impl/SKILL.md @@ -1,8 +1,8 @@ --- -description: Read relevant PhysioMotion4D source files, summarize current behavior, propose a brief plan, then implement the requested feature or refactor in small diffs. Calls out breaking changes. +description: Read relevant PhysioTwin4D source files, summarize current behavior, propose a brief plan, then implement the requested feature or refactor in small diffs. Calls out breaking changes. --- -Implement the following in the PhysioMotion4D repository: +Implement the following in the PhysioTwin4D repository: $ARGUMENTS diff --git a/.agents/skills/plan/SKILL.md b/.agents/skills/plan/SKILL.md index 144d342..5622ab5 100644 --- a/.agents/skills/plan/SKILL.md +++ b/.agents/skills/plan/SKILL.md @@ -1,8 +1,8 @@ --- -description: Inspect PhysioMotion4D source files, summarize the current design, and produce a numbered implementation plan with open questions. Does not write code unless explicitly asked. +description: Inspect PhysioTwin4D source files, summarize the current design, and produce a numbered implementation plan with open questions. Does not write code unless explicitly asked. --- -Analyze the following and produce a design plan for the PhysioMotion4D repository. +Analyze the following and produce a design plan for the PhysioTwin4D repository. Task: $ARGUMENTS diff --git a/.agents/skills/regen-api-map/SKILL.md b/.agents/skills/regen-api-map/SKILL.md index d9baf89..b346da6 100644 --- a/.agents/skills/regen-api-map/SKILL.md +++ b/.agents/skills/regen-api-map/SKILL.md @@ -1,8 +1,8 @@ --- -description: Regenerate docs/API_MAP.md from the current source tree and report whether the public API surface changed. Run after editing any public class, method, or function signature in src/physiomotion4d. +description: Regenerate docs/API_MAP.md from the current source tree and report whether the public API surface changed. Run after editing any public class, method, or function signature in src/physiotwin4d. --- -Regenerate the PhysioMotion4D API map and report what changed. +Regenerate the PhysioTwin4D API map and report what changed. $ARGUMENTS diff --git a/.agents/skills/test-feature/SKILL.md b/.agents/skills/test-feature/SKILL.md index ff061d6..2acaa19 100644 --- a/.agents/skills/test-feature/SKILL.md +++ b/.agents/skills/test-feature/SKILL.md @@ -1,8 +1,8 @@ --- -description: Inspect a PhysioMotion4D implementation and its existing tests, propose a real-data-driven test plan with baseline comparisons, then create or update pytest tests. Explains how to run them. +description: Inspect a PhysioTwin4D implementation and its existing tests, propose a real-data-driven test plan with baseline comparisons, then create or update pytest tests. Explains how to run them. --- -Write or update tests for the following in PhysioMotion4D: +Write or update tests for the following in PhysioTwin4D: $ARGUMENTS diff --git a/.cursor/rules/project-standards.mdc b/.cursor/rules/project-standards.mdc index 0c61c42..6769f2c 100644 --- a/.cursor/rules/project-standards.mdc +++ b/.cursor/rules/project-standards.mdc @@ -1,9 +1,9 @@ --- -description: PhysioMotion4D project standards and workflow preferences +description: PhysioTwin4D project standards and workflow preferences alwaysApply: true --- -# PhysioMotion4D Project Standards +# PhysioTwin4D Project Standards ## File Operations diff --git a/.github/scripts/build_dashboard.py b/.github/scripts/build_dashboard.py index cc07503..601e6d2 100644 --- a/.github/scripts/build_dashboard.py +++ b/.github/scripts/build_dashboard.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Build the nightly health dashboard for PhysioMotion4D. +Build the nightly health dashboard for PhysioTwin4D. Reads JUnit XML test results and coverage JSON from --results-dir, generates an HTML dashboard (index.html), a shields.io-compatible @@ -11,7 +11,7 @@ python .github/scripts/build_dashboard.py \\ --results-dir results/ \\ --output-dir dashboard/ \\ - --run-url "https://github.com/Project-MONAI/physiomotion4d/actions/runs/123" \\ + --run-url "https://github.com/Project-MONAI/physiotwin4d/actions/runs/123" \\ --timestamp "2026-03-31T07:05:42Z" \\ --health-outcome "success" @@ -205,11 +205,11 @@ def build_html(data: dict) -> str: -PhysioMotion4D — Nightly Health +PhysioTwin4D — Nightly Health -

PhysioMotion4D — Nightly Health

+

PhysioTwin4D — Nightly Health

Last run: {ts_display} ·  {badge_label} ·  @@ -240,11 +240,11 @@ def build_html(data: dict) -> str:

@@ -260,7 +260,7 @@ def build_status_json(data: dict) -> dict: """Return a shields.io dynamic endpoint object. Usage in README: - ![Health](https://img.shields.io/endpoint?url=https://project-monai.github.io/physiomotion4d/status.json) + ![Health](https://img.shields.io/endpoint?url=https://project-monai.github.io/physiotwin4d/status.json) """ junit = data["junit"] @@ -313,7 +313,7 @@ def build_summary_md(data: dict) -> str: status_text = "Passing" lines = [ - f"# {status_icon} PhysioMotion4D Nightly Health — {ts_display}", + f"# {status_icon} PhysioTwin4D Nightly Health — {ts_display}", "", f"**Status:** {status_text}   |   [View run]({run_url})", "", @@ -354,7 +354,7 @@ def build_summary_md(data: dict) -> str: def main() -> None: parser = argparse.ArgumentParser( - description="Build PhysioMotion4D nightly health dashboard" + description="Build PhysioTwin4D nightly health dashboard" ) parser.add_argument( "--results-dir", diff --git a/.github/workflows/README.md b/.github/workflows/README.md index ec1fdc1..4e22ee1 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -213,7 +213,7 @@ pip install -e ".[test]" pytest tests/ -m "unit and not requires_gpu" # Run with coverage -pytest tests/ -m "unit and not requires_gpu" --cov=physiomotion4d +pytest tests/ -m "unit and not requires_gpu" --cov=physiotwin4d ``` ### GPU Tests diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f25df8..6a3190e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,12 +111,12 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | xvfb-run -a --server-args="-screen 0 1024x768x24" \ - pytest tests/ -v --cov=physiomotion4d --cov-report=xml --cov-report=term --cov-report=html + pytest tests/ -v --cov=physiotwin4d --cov-report=xml --cov-report=term --cov-report=html - name: Run unit tests (fast, no GPU/slow/experiment) - Windows if: matrix.os == 'windows-latest' run: | - pytest tests/ -v --cov=physiomotion4d --cov-report=xml --cov-report=term --cov-report=html + pytest tests/ -v --cov=physiotwin4d --cov-report=xml --cov-report=term --cov-report=html - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 @@ -220,29 +220,29 @@ jobs: - name: Run data download tests run: | - pytest tests/test_download_heart_data.py -v --cov=physiomotion4d --cov-report=xml + pytest tests/test_download_heart_data.py -v --cov=physiotwin4d --cov-report=xml continue-on-error: true - name: Run data conversion tests run: | - pytest tests/test_convert_image_4d_to_3d.py -v --cov=physiomotion4d --cov-append --cov-report=xml + pytest tests/test_convert_image_4d_to_3d.py -v --cov=physiotwin4d --cov-append --cov-report=xml continue-on-error: true - name: Run contour tools tests run: | - pytest tests/test_contour_tools.py -v --cov=physiomotion4d --cov-append --cov-report=xml + pytest tests/test_contour_tools.py -v --cov=physiotwin4d --cov-append --cov-report=xml continue-on-error: true - name: Run USD conversion tests run: | xvfb-run -a --server-args="-screen 0 1024x768x24" \ - pytest tests/test_convert_vtk_to_usd_polymesh.py -v --cov=physiomotion4d --cov-append --cov-report=xml + pytest tests/test_convert_vtk_to_usd_polymesh.py -v --cov=physiotwin4d --cov-append --cov-report=xml continue-on-error: true - name: Run USD utility tests run: | xvfb-run -a --server-args="-screen 0 1024x768x24" \ - pytest tests/test_usd_merge.py tests/test_usd_time_preservation.py -v --cov=physiomotion4d --cov-append --cov-report=xml + pytest tests/test_usd_merge.py tests/test_usd_time_preservation.py -v --cov=physiotwin4d --cov-append --cov-report=xml continue-on-error: true - name: Run all integration tests @@ -285,8 +285,8 @@ jobs: # Python 3.11 is required because the [physicsnemo] extra pulls in # nvidia-physicsnemo, which requires Python >= 3.11. run: | - & "C:\Program Files\Python311\python.exe" -m venv "$env:RUNNER_TEMP\physiomotion4d-venv" - echo "$env:RUNNER_TEMP\physiomotion4d-venv\Scripts" >> $env:GITHUB_PATH + & "C:\Program Files\Python311\python.exe" -m venv "$env:RUNNER_TEMP\physiotwin4d-venv" + echo "$env:RUNNER_TEMP\physiotwin4d-venv\Scripts" >> $env:GITHUB_PATH - name: Check GPU availability run: nvidia-smi @@ -340,7 +340,7 @@ jobs: # aren't met on the runner will runtime-skip cleanly via their # internal availability guards. run: | - pytest tests/ -v --run-all --cov=physiomotion4d --cov-report=xml --cov-report=term --cov-report=html + pytest tests/ -v --run-all --cov=physiotwin4d --cov-report=xml --cov-report=term --cov-report=html env: CUDA_VISIBLE_DEVICES: 0 diff --git a/.github/workflows/nightly-health.yml b/.github/workflows/nightly-health.yml index ce10a05..31e9bb8 100644 --- a/.github/workflows/nightly-health.yml +++ b/.github/workflows/nightly-health.yml @@ -13,7 +13,7 @@ name: Nightly Health # documentation site published by docs.yml. Use the workflow status badge # for a live pass/fail indicator in README: # -# [![Nightly Health](https://github.com/Project-MONAI/physiomotion4d/actions/workflows/nightly-health.yml/badge.svg)](https://github.com/Project-MONAI/physiomotion4d/actions/workflows/nightly-health.yml) +# [![Nightly Health](https://github.com/Project-MONAI/physiotwin4d/actions/workflows/nightly-health.yml/badge.svg)](https://github.com/Project-MONAI/physiotwin4d/actions/workflows/nightly-health.yml) on: schedule: @@ -58,8 +58,8 @@ jobs: # Python 3.11 is required because the [physicsnemo] extra pulls in # nvidia-physicsnemo, which requires Python >= 3.11. run: | - & py -m venv "$env:RUNNER_TEMP\physiomotion4d-venv" - echo "$env:RUNNER_TEMP\physiomotion4d-venv\Scripts" >> $env:GITHUB_PATH + & py -m venv "$env:RUNNER_TEMP\physiotwin4d-venv" + echo "$env:RUNNER_TEMP\physiotwin4d-venv\Scripts" >> $env:GITHUB_PATH - name: Cache uv packages uses: actions/cache@v4 @@ -113,7 +113,7 @@ jobs: continue-on-error: true run: | pytest tests/ -v --run-all ` - --cov=physiomotion4d ` + --cov=physiotwin4d ` --cov-report=xml ` --cov-report=json ` --junitxml=test-results.xml diff --git a/.github/workflows/test-slow.yml b/.github/workflows/test-slow.yml index 3bfc9cc..34bad2a 100644 --- a/.github/workflows/test-slow.yml +++ b/.github/workflows/test-slow.yml @@ -24,8 +24,8 @@ jobs: # Python 3.11 is required because the [physicsnemo] extra pulls in # nvidia-physicsnemo, which requires Python >= 3.11. run: | - & "C:\Program Files\Python311\python.exe" -m venv "$env:RUNNER_TEMP\physiomotion4d-venv" - echo "$env:RUNNER_TEMP\physiomotion4d-venv\Scripts" >> $env:GITHUB_PATH + & "C:\Program Files\Python311\python.exe" -m venv "$env:RUNNER_TEMP\physiotwin4d-venv" + echo "$env:RUNNER_TEMP\physiotwin4d-venv\Scripts" >> $env:GITHUB_PATH - name: Check GPU availability run: nvidia-smi @@ -81,7 +81,7 @@ jobs: # aren't met on the runner will runtime-skip cleanly via their # internal availability guards. run: | - pytest tests/ -v --run-all --cov=physiomotion4d --cov-report=xml --cov-report=term + pytest tests/ -v --run-all --cov=physiotwin4d --cov-report=xml --cov-report=term env: CUDA_VISIBLE_DEVICES: 0 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d98cac4..b57a603 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,4 +1,4 @@ -# Read the Docs configuration file for PhysioMotion4D +# Read the Docs configuration file for PhysioTwin4D # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details version: 2 diff --git a/AGENTS.md b/AGENTS.md index 4def792..a566903 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ Role-based guidance for AI agents working in this repository. -PhysioMotion4D converts 4D CT scans into animated USD models for NVIDIA +PhysioTwin4D converts 4D CT scans into animated USD models for NVIDIA Omniverse. It is an **early-alpha** scientific Python library. Clarity beats premature optimization. Breaking changes are acceptable. Backward compatibility is not a goal. @@ -87,7 +87,7 @@ python -m pytest tests/ -v --run-all python -m pytest tests/ -v --run-gpu --run-slow # Coverage -python -m pytest tests/ --cov=src/physiomotion4d --cov-report=html +python -m pytest tests/ --cov=src/physiotwin4d --cov-report=html # Create missing baselines python -m pytest tests/ --create-baselines @@ -102,7 +102,7 @@ Version bumping: `bumpver update --patch`, `--minor`, or `--major`. do not assume Python 3.11 is missing. The Codex sandbox can break the launcher or venv path. - Use the temporary validation environment instead: - `C:\Users\saylward\AppData\Local\Temp\pm4d-uv-env\Scripts\python.exe`. + `C:\Users\saylward\AppData\Local\Temp\pt4d-uv-env\Scripts\python.exe`. It has been verified as Python 3.11.9 with `ruff` available. - Run that temporary venv outside the sandbox when needed. Treat this as an environment/sandbox workaround, not a dependency or installation problem. @@ -111,9 +111,9 @@ Version bumping: `bumpver update --patch`, `--minor`, or `--major`. - Read the relevant source files before proposing changes. - Runtime classes for workflows, segmentation, registration, and USD tools - inherit from `PhysioMotion4DBase`; new runtime classes must too. Standalone + inherit from `PhysioTwin4DBase`; new runtime classes must too. Standalone utility scripts and data/container/helper classes do not. -- In classes that inherit from `PhysioMotion4DBase`, use `self.log_info()` and +- In classes that inherit from `PhysioTwin4DBase`, use `self.log_info()` and `self.log_debug()`, never `print()`. Standalone scripts may use `print()`. - No emojis in `.py` files; avoid them in docs too. Windows cp1252 encoding has broken this project before. @@ -182,7 +182,7 @@ Version bumping: `bumpver update --patch`, `--minor`, or `--major`. - State image shape and axis order in every test docstring, for example: `shape (X, Y, Z, T) = (64, 64, 32, 1), LPS world frame`. - When a test produces an image or surface, compare against a baseline using - `src/physiomotion4d/test_tools.py` utilities such as `TestTools`. + `src/physiotwin4d/test_tools.py` utilities such as `TestTools`. - Store baselines under `tests/baselines/`, which is tracked by Git LFS. Run `git lfs pull` after cloning. - Run with `--create-baselines` to materialize missing baselines on first use. diff --git a/CLAUDE.md b/CLAUDE.md index 70288bb..ec23b5c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -62,7 +62,7 @@ py -m pytest tests/ -v --run-all py -m pytest tests/ -v --run-gpu --run-slow # With coverage -py -m pytest tests/ --cov=src/physiomotion4d --cov-report=html +py -m pytest tests/ --cov=src/physiotwin4d --cov-report=html # Create missing baselines py -m pytest tests/ --create-baselines @@ -72,7 +72,7 @@ py -m pytest tests/ --create-baselines ## Architecture -All classes inherit from `PhysioMotion4DBase` (`physiomotion4d_base.py`), which provides +All classes inherit from `PhysioTwin4DBase` (`physiotwin4d_base.py`), which provides a shared logger. Use `self.log_info()`, `self.log_debug()` — never `print()`. Consult `docs/API_MAP.md` for the full index of classes, methods, and signatures. @@ -93,7 +93,7 @@ Regenerate it after any public API change: `py utils/generate_api_map.py` - Baselines in `tests/baselines/` via Git LFS — run `git lfs pull` after cloning - `tests/conftest.py`: session-scoped fixtures chaining download → convert → segment → register -- `src/physiomotion4d/test_tools.py`: baseline comparison utilities (`TestTools`, etc.) +- `src/physiotwin4d/test_tools.py`: baseline comparison utilities (`TestTools`, etc.) - Markers (all opt-in via `--run-`): `slow`, `requires_gpu`, `requires_simpleware`, `experiment`, `tutorial`. Data-dependent tests no longer use a marker — they pull data through fixtures and run by default. diff --git a/MANIFEST.in b/MANIFEST.in index c79309b..6dcaf39 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -17,12 +17,12 @@ recursive-include scripts *.md recursive-include src *.py # Include network weights and models -recursive-include src/physiomotion4d/network_weights * +recursive-include src/physiotwin4d/network_weights * # Include data files -recursive-include src/physiomotion4d *.json -recursive-include src/physiomotion4d *.yaml -recursive-include src/physiomotion4d *.yml +recursive-include src/physiotwin4d *.json +recursive-include src/physiotwin4d *.yaml +recursive-include src/physiotwin4d *.yml # Exclude unnecessary files global-exclude __pycache__ diff --git a/README.md b/README.md index 932abce..185a59b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# PhysioMotion4D +# PhysioTwin4D **Generate anatomic models in Omniverse with physiological motion derived from 4D medical images.** -PhysioMotion4D is a comprehensive medical imaging package that converts 4D CT scans (particularly heart and lung gated CT data) into dynamic 3D models for visualization in NVIDIA Omniverse. The package provides state-of-the-art deep learning-based image processing, segmentation, registration, and USD file generation capabilities. +PhysioTwin4D is a comprehensive medical imaging package that converts 4D CT scans (particularly heart and lung gated CT data) into dynamic 3D models for visualization in NVIDIA Omniverse. The package provides state-of-the-art deep learning-based image processing, segmentation, registration, and USD file generation capabilities. ## Documentation Start with the hosted documentation: -**https://project-monai.github.io/physiomotion4d/** +**https://project-monai.github.io/physiotwin4d/** The documentation is the primary entry point for users and contributors. It includes: @@ -24,7 +24,7 @@ includes: - **Contributing, Testing, and Troubleshooting**: project practices, validation commands, and common setup issues. -> **Not validated for clinical use.** PhysioMotion4D is a 2026.05.07 beta +> **Not validated for clinical use.** PhysioTwin4D is a 2026.07.0 beta > research and visualization toolkit. It is not a medical device and must not > be used for diagnosis, treatment planning, or clinical decision-making. @@ -59,10 +59,10 @@ includes: ```bash # CPU-only PyPI install — works out of the box; a runtime warning points to the GPU extra -pip install physiomotion4d +pip install physiotwin4d # CUDA 13 install (recommended for production) -uv pip install "physiomotion4d[cuda13]" +uv pip install "physiotwin4d[cuda13]" ``` The `[cuda13]` extra installs CuPy. In uv-managed source environments, PyTorch, @@ -74,18 +74,18 @@ a large CUDA-only toolchain and narrows supported Python versions. Install it explicitly when needed: ```bash -pip install "physiomotion4d[physicsnemo]" +pip install "physiotwin4d[physicsnemo]" ``` -PhysicsNeMo itself requires Python >= 3.11. PhysioMotion4D otherwise supports +PhysicsNeMo itself requires Python >= 3.11. PhysioTwin4D otherwise supports Python >= 3.10. ### Installation from Source 1. **Clone the repository** (Git LFS is required for tests; install it first from [git-lfs.github.com](https://git-lfs.github.com)): ```bash - git clone https://github.com/Project-MONAI/physiomotion4d.git - cd physiomotion4d + git clone https://github.com/Project-MONAI/physiotwin4d.git + cd physiotwin4d git lfs install # if not already done git lfs pull # fetch .hdf and .mha baselines in tests/baselines/ ``` @@ -101,7 +101,7 @@ Python >= 3.10. pip install uv ``` -4. **Install PhysioMotion4D**: +4. **Install PhysioTwin4D**: ```bash # CUDA 13 PyTorch is the default for uv-managed source environments uv pip install -e "." @@ -113,10 +113,10 @@ Python >= 3.10. ### Verify Installation ```python -import physiomotion4d -from physiomotion4d import WorkflowConvertImageToUSD +import physiotwin4d +from physiotwin4d import WorkflowConvertImageToUSD -print(f"PhysioMotion4D version: {physiomotion4d.__version__}") +print(f"PhysioTwin4D version: {physiotwin4d.__version__}") print(WorkflowConvertImageToUSD.__name__) ``` @@ -142,7 +142,7 @@ print(WorkflowConvertImageToUSD.__name__) - `RegisterModelsDistanceMaps`: Mask-based deformable model registration - `RegisterImagesBase`: Base class for custom registration methods - **Base Classes**: Foundation classes providing common functionality - - `PhysioMotion4DBase`: Base class providing standardized logging and debug settings + - `PhysioTwin4DBase`: Base class providing standardized logging and debug settings - **Utility Classes**: Tools for data manipulation and conversion - `TransformTools`: Comprehensive transform manipulation utilities - `USDTools`: USD file manipulation for Omniverse integration @@ -179,7 +179,7 @@ variants). They are the recommended starting point for new users. | 4 | `tutorials/tutorial_04_fit_statistical_model_to_patient.py` | Fit statistical model to patient | KCL-Heart-Model plus Tutorial 3 output | | 5 | `tutorials/tutorial_05_vtk_to_usd.py` | VTK surfaces to animated USD | output of tutorial 2 | | 6 | `tutorials/tutorial_06_reconstruct_highres_4d_ct.py` | Reconstruct high-res 4D CT | DirLab-4DCT (manual) | -| 8 | `tutorials/tutorial_08_cardiac_fit_model.py` | Fit the cardiac PCA model and propagate it through gated phases | Bring your own (`D:/PhysioMotion4D/`) | +| 8 | `tutorials/tutorial_08_cardiac_fit_model.py` | Fit the cardiac PCA model and propagate it through gated phases | Bring your own (`D:/PhysioTwin4D/`) | | 9a | `tutorials/tutorial_09a_cardiac_train_physicsnemo_mgn.py` | Train a PhysicsNeMo MeshGraphNet cardiac stage model (requires `[physicsnemo]` + `torch-geometric`; Python >= 3.11) | Tutorial 8 output | | 9b | `tutorials/tutorial_09b_cardiac_train_physicsnemo_mlp.py` | Train a PhysicsNeMo MLP cardiac stage model (requires `[physicsnemo]` extra; Python >= 3.11) | Tutorial 8 output | | 10a | `tutorials/tutorial_10a_cardiac_eval_physicsnemo_mgn.py` | Predict / score cardiac surfaces from a MeshGraphNet checkpoint | Tutorial 9a checkpoint | @@ -187,7 +187,7 @@ variants). They are the recommended starting point for new users. Each tutorial is a `# %%` percent-cell Python script. Paths are defined near the top of the script; edit those constants for custom data/output locations, -or use the installed `physiomotion4d-*` CLI commands when you want path +or use the installed `physiotwin4d-*` CLI commands when you want path arguments. ```bash @@ -207,9 +207,9 @@ This quickstart uses the public Slicer-Heart 4D CT sample. Data downloading and a CUDA-capable GPU are required for practical runtime. ```bash -python -c "from physiomotion4d import DataDownloadTools; DataDownloadTools.DownloadSlicerHeartCTData('data/test')" +python -c "from physiotwin4d import DataDownloadTools; DataDownloadTools.DownloadSlicerHeartCTData('data/test')" -physiomotion4d-convert-image-to-usd data/test/TruncalValve_4DCT.seq.nrrd \ +physiotwin4d-convert-image-to-usd data/test/TruncalValve_4DCT.seq.nrrd \ --registration-method ANTS \ --output-dir output/quickstart \ --project-name slicer_heart_quickstart @@ -219,7 +219,7 @@ physiomotion4d-convert-image-to-usd data/test/TruncalValve_4DCT.seq.nrrd \ ### Command-Line Interface -After installation, PhysioMotion4D provides command-line tools that are automatically added to your PATH: +After installation, PhysioTwin4D provides command-line tools that are automatically added to your PATH: #### Heart-Gated CT to USD @@ -227,20 +227,20 @@ Process 4D cardiac CT images into dynamic USD models: ```bash # Process a single 4D cardiac CT file -physiomotion4d-convert-image-to-usd cardiac_4d.nrrd --contrast --output-dir ./results +physiotwin4d-convert-image-to-usd cardiac_4d.nrrd --contrast --output-dir ./results # Process multiple time frames -physiomotion4d-convert-image-to-usd frame_*.nrrd --contrast --project-name patient_001 +physiotwin4d-convert-image-to-usd frame_*.nrrd --contrast --project-name patient_001 # With custom settings -physiomotion4d-convert-image-to-usd cardiac.nrrd \ +physiotwin4d-convert-image-to-usd cardiac.nrrd \ --contrast \ --reference-image ref.mha \ --registration-iterations 50 \ --output-dir ./output ``` -For Python API usage and advanced customization, see the examples below or refer to the CLI implementation in `src/physiomotion4d/cli/`. +For Python API usage and advanced customization, see the examples below or refer to the CLI implementation in `src/physiotwin4d/cli/`. #### Create Statistical Model @@ -248,13 +248,13 @@ Build a PCA statistical shape model from sample meshes aligned to a reference: ```bash # From a directory of sample meshes -physiomotion4d-create-statistical-model \ +physiotwin4d-create-statistical-model \ --sample-meshes-dir ./input_meshes \ --reference-mesh average_mesh.vtk \ --output-dir ./pca_output # With custom PCA components -physiomotion4d-create-statistical-model \ +physiotwin4d-create-statistical-model \ --sample-meshes-dir ./meshes \ --reference-mesh average_mesh.vtk \ --output-dir ./pca_output \ @@ -269,7 +269,7 @@ Register a generic heart model to patient-specific data: ```bash # Basic registration -physiomotion4d-fit-statistical-model-to-patient \ +physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp myo.vtp \ @@ -277,7 +277,7 @@ physiomotion4d-fit-statistical-model-to-patient \ --output-dir ./results # With PCA shape fitting -physiomotion4d-fit-statistical-model-to-patient \ +physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp myo.vtp \ @@ -287,12 +287,12 @@ physiomotion4d-fit-statistical-model-to-patient \ --output-dir ./results ``` -For implementation details and advanced usage, see the CLI modules in `src/physiomotion4d/cli/`. +For implementation details and advanced usage, see the CLI modules in `src/physiotwin4d/cli/`. ### Python API - Basic Heart-Gated CT Processing ```python -from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD +from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD # Initialize processor processor = WorkflowConvertImageToUSD( @@ -309,7 +309,7 @@ final_usd = processor.process() ### Python API - Model to Patient Registration ```python -from physiomotion4d import WorkflowFitStatisticalModelToPatient +from physiotwin4d import WorkflowFitStatisticalModelToPatient import pyvista as pv import itk @@ -333,7 +333,7 @@ registered_mesh = result["registered_template_model_surface"] ### Custom Segmentation ```python -from physiomotion4d import SegmentChestTotalSegmentatorWithContrast +from physiotwin4d import SegmentChestTotalSegmentatorWithContrast import itk # Use SegmentChestTotalSegmentator instead for non-contrast studies @@ -357,7 +357,7 @@ if "lung" in masks: ### Image Registration ```python -from physiomotion4d import RegisterImagesICON, RegisterImagesANTS, RegisterTimeSeriesImages +from physiotwin4d import RegisterImagesICON, RegisterImagesANTS, RegisterTimeSeriesImages import itk # Option 1: Icon deep learning registration (GPU-accelerated) @@ -390,12 +390,12 @@ forward_transform = results["forward_transform"] # Moving to fixed ### VTK to USD Conversion -PhysioMotion4D provides two APIs for converting VTK data to USD for NVIDIA Omniverse visualization. Repository workflows, experiments, and CLIs use `ConvertVTKToUSD`; `vtk_to_usd` is a public advanced layer for users who need low-level file conversion primitives. +PhysioTwin4D provides two APIs for converting VTK data to USD for NVIDIA Omniverse visualization. Repository workflows, experiments, and CLIs use `ConvertVTKToUSD`; `vtk_to_usd` is a public advanced layer for users who need low-level file conversion primitives. #### Option 1: High-Level ConvertVTKToUSD (for PyVista/VTK objects) ```python -from physiomotion4d import ConvertVTKToUSD, SegmentChestTotalSegmentator +from physiotwin4d import ConvertVTKToUSD, SegmentChestTotalSegmentator import pyvista as pv # Load VTK data @@ -427,7 +427,7 @@ stage = converter.convert('cardiac_motion.usd') #### Option 2: Advanced File-Based vtk_to_usd Facade ```python -from physiomotion4d.vtk_to_usd import ( +from physiotwin4d.vtk_to_usd import ( ConversionSettings, MaterialData, convert_vtk_file, @@ -467,26 +467,26 @@ Features: ### Logging and Debug Control -PhysioMotion4D provides standardized logging through the `PhysioMotion4DBase` class, which is inherited by workflow and registration classes. +PhysioTwin4D provides standardized logging through the `PhysioTwin4DBase` class, which is inherited by workflow and registration classes. ```python import logging -from physiomotion4d import WorkflowFitStatisticalModelToPatient, PhysioMotion4DBase +from physiotwin4d import WorkflowFitStatisticalModelToPatient, PhysioTwin4DBase # Control logging level globally for all classes -PhysioMotion4DBase.set_log_level(logging.DEBUG) +PhysioTwin4DBase.set_log_level(logging.DEBUG) # Or filter to show logs from specific classes only -PhysioMotion4DBase.set_log_classes(["WorkflowFitStatisticalModelToPatient", "RegisterModelsPCA"]) +PhysioTwin4DBase.set_log_classes(["WorkflowFitStatisticalModelToPatient", "RegisterModelsPCA"]) # Show all classes again -PhysioMotion4DBase.set_log_all_classes() +PhysioTwin4DBase.set_log_all_classes() # Query which classes are currently filtered -filtered = PhysioMotion4DBase.get_log_classes() +filtered = PhysioTwin4DBase.get_log_classes() ``` -Classes that inherit from `PhysioMotion4DBase` provide: +Classes that inherit from `PhysioTwin4DBase` provide: - Standard log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL - Progress reporting for long-running operations - Class-based log filtering @@ -605,7 +605,7 @@ The Slicer-Heart sample can be downloaded directly from its public GitHub release: ```python -from physiomotion4d import DataDownloadTools +from physiotwin4d import DataDownloadTools data_file = DataDownloadTools.DownloadSlicerHeartCTData("data/Slicer-Heart-CT") assert DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT") @@ -615,7 +615,7 @@ assert DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT") ### Code Quality Tools -PhysioMotion4D uses modern, fast tooling for code quality: +PhysioTwin4D uses modern, fast tooling for code quality: - **Ruff**: Fast linting and formatting (replaces black, isort, flake8, pylint) - **mypy**: Type checking @@ -646,7 +646,7 @@ See `docs/contributing.rst` for complete IDE setup instructions. ### Testing -PhysioMotion4D includes comprehensive tests covering the complete pipeline from data download to USD generation. +PhysioTwin4D includes comprehensive tests covering the complete pipeline from data download to USD generation. ```bash # Fast tests (recommended for development). @@ -679,7 +679,7 @@ pytest tests/test_image_tools.py -v # Image processing u pytest tests/test_transform_tools.py -v --run-slow # Transform operations # Run with coverage report -pytest tests/ --cov=src/physiomotion4d --cov-report=html +pytest tests/ --cov=src/physiotwin4d --cov-report=html ``` **Test Categories:** @@ -836,7 +836,7 @@ without writing any code. ## Additional Documentation The canonical documentation is published at -https://project-monai.github.io/physiomotion4d/. +https://project-monai.github.io/physiotwin4d/. Use it for tutorials, getting started, CLI usage, API reference, developer guides, contributing, testing, and troubleshooting. The `experiments/` @@ -875,4 +875,4 @@ This project is licensed under the Apache 2.0 License - see the LICENSE file for --- -**Get started with the tutorial scripts under `tutorials/` to see PhysioMotion4D in action.** +**Get started with the tutorial scripts under `tutorials/` to see PhysioTwin4D in action.** diff --git a/data/KCL-Heart-Model/README.md b/data/KCL-Heart-Model/README.md index 866fc3a..bf77556 100644 --- a/data/KCL-Heart-Model/README.md +++ b/data/KCL-Heart-Model/README.md @@ -50,7 +50,7 @@ If you use this dataset, please cite: ## Using This Dataset -This dataset is used in the PhysioMotion4D experiments for creating statistical shape models and patient-specific heart registrations. +This dataset is used in the PhysioTwin4D experiments for creating statistical shape models and patient-specific heart registrations. ### Heart-Create_Statistical_Model Experiment diff --git a/data/README.md b/data/README.md index ffc9aaf..4e5028c 100644 --- a/data/README.md +++ b/data/README.md @@ -1,6 +1,6 @@ -# PhysioMotion4D Data Directory +# PhysioTwin4D Data Directory -This directory contains sample datasets used for experiments, testing, and development of the PhysioMotion4D library. Each subdirectory contains a specific medical imaging dataset. +This directory contains sample datasets used for experiments, testing, and development of the PhysioTwin4D library. Each subdirectory contains a specific medical imaging dataset. ## Directory Structure @@ -48,7 +48,7 @@ Data provided by Jolley Lab at CHOP (Children's Hospital of Philadelphia): **Automatic download** (recommended): ```python -from physiomotion4d import DataDownloadTools +from physiotwin4d import DataDownloadTools DataDownloadTools.DownloadSlicerHeartCTData("data/Slicer-Heart-CT") assert DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT") @@ -68,11 +68,11 @@ wget https://github.com/Slicer-Heart-CT/Slicer-Heart-CT/releases/download/Testin ### Verification Helpers -PhysioMotion4D exposes a small public utility for checking optional dataset +PhysioTwin4D exposes a small public utility for checking optional dataset layouts: ```python -from physiomotion4d import DataDownloadTools +from physiotwin4d import DataDownloadTools DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT") DataDownloadTools.VerifyDirLab4DCTData("data/DirLab-4DCT") diff --git a/data/Slicer-Heart-CT/download_and_convert.py b/data/Slicer-Heart-CT/download_and_convert.py index 525777e..535ba19 100644 --- a/data/Slicer-Heart-CT/download_and_convert.py +++ b/data/Slicer-Heart-CT/download_and_convert.py @@ -3,8 +3,8 @@ import os import shutil -from physiomotion4d.convert_image_4d_to_3d import ConvertImage4DTo3D -from physiomotion4d.data_download_tools import DataDownloadTools +from physiotwin4d.convert_image_4d_to_3d import ConvertImage4DTo3D +from physiotwin4d.data_download_tools import DataDownloadTools # %% data_dir = "." diff --git a/docs/PYPI_RELEASE_GUIDE.md b/docs/PYPI_RELEASE_GUIDE.md index c670794..be2bef0 100644 --- a/docs/PYPI_RELEASE_GUIDE.md +++ b/docs/PYPI_RELEASE_GUIDE.md @@ -1,6 +1,6 @@ -# PyPI Release Guide for PhysioMotion4D +# PyPI Release Guide for PhysioTwin4D -This guide provides step-by-step instructions for building and uploading PhysioMotion4D to PyPI. +This guide provides step-by-step instructions for building and uploading PhysioTwin4D to PyPI. ## Prerequisites @@ -47,7 +47,7 @@ password = pypi-AgENdGVzdC5weXBp... # Your TestPyPI token Edit `pyproject.toml`: ```toml [tool.bumpver] -current_version = "2026.05.07" # Update this +current_version = "2026.07.0" # Update this ``` Or use bumpver: @@ -94,11 +94,11 @@ pytest tests/ pip install -e . # Verify imports -python -c "import physiomotion4d; print(physiomotion4d.__version__)" +python -c "import physiotwin4d; print(physiotwin4d.__version__)" # Test CLI commands -physiomotion4d --help -physiomotion4d-convert-image-to-usd --help +physiotwin4d --help +physiotwin4d-convert-image-to-usd --help ``` ## Building the Package @@ -118,17 +118,17 @@ python -m build ``` This creates: -- `dist/physiomotion4d-2026.05.07.tar.gz` (source distribution) -- `dist/physiomotion4d-2026.05.07-py3-none-any.whl` (wheel distribution) +- `dist/physiotwin4d-2026.07.0.tar.gz` (source distribution) +- `dist/physiotwin4d-2026.07.0-py3-none-any.whl` (wheel distribution) ### 3. Verify Build Contents ```bash # List contents of the wheel -unzip -l dist/physiomotion4d-*.whl +unzip -l dist/physiotwin4d-*.whl # Check if all necessary files are included -tar -tzf dist/physiomotion4d-*.tar.gz +tar -tzf dist/physiotwin4d-*.tar.gz ``` ## Testing on TestPyPI (Recommended) @@ -149,7 +149,7 @@ source test_env/bin/activate # On Windows: test_env\Scripts\activate # Install from TestPyPI pip install --index-url https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple \ - physiomotion4d + physiotwin4d ``` Note: `--extra-index-url` is needed because dependencies are on PyPI, not TestPyPI. @@ -158,16 +158,16 @@ Note: `--extra-index-url` is needed because dependencies are on PyPI, not TestPy ```python # Test imports -import physiomotion4d -from physiomotion4d import WorkflowConvertImageToUSD +import physiotwin4d +from physiotwin4d import WorkflowConvertImageToUSD -print(f"Version: {physiomotion4d.__version__}") +print(f"Version: {physiotwin4d.__version__}") print(WorkflowConvertImageToUSD.__name__) ``` ```bash # Test CLI -physiomotion4d-convert-image-to-usd --help +physiotwin4d-convert-image-to-usd --help ``` ## Publishing to PyPI @@ -189,7 +189,7 @@ twine upload dist/* ### 3. Verify Upload -Visit: https://pypi.org/project/physiomotion4d/ +Visit: https://pypi.org/project/physiotwin4d/ ### 4. Test Installation from PyPI @@ -199,10 +199,10 @@ python -m venv pypi_test source pypi_test/bin/activate # Install from PyPI -pip install physiomotion4d +pip install physiotwin4d # Verify -python -c "import physiomotion4d; print(physiomotion4d.__version__)" +python -c "import physiotwin4d; print(physiotwin4d.__version__)" ``` ## Post-Release Steps @@ -210,14 +210,14 @@ python -c "import physiomotion4d; print(physiomotion4d.__version__)" ### 1. Tag the Release in Git ```bash -git tag -a v2026.05.07 -m "Release version 2026.05.07" -git push origin v2026.05.07 +git tag -a v2026.07.0 -m "Release version 2026.07.0" +git push origin v2026.07.0 ``` ### 2. Create GitHub/GitLab Release Create a release on your repository with: -- Tag: `v2026.05.07` +- Tag: `v2026.07.0` - Release notes from `docs/changelog.rst` - Attach distribution files (optional) @@ -240,7 +240,7 @@ Create a release on your repository with: **Problem**: Import errors after installation ```bash # Solution: Verify package structure -# Check that src/physiomotion4d/__init__.py exports necessary classes +# Check that src/physiotwin4d/__init__.py exports necessary classes ``` ### Upload Errors @@ -297,7 +297,7 @@ python -m build --sdist pip install -e ".[dev,test]" # View package information -python -m pip show physiomotion4d +python -m pip show physiotwin4d ``` ## Best Practices diff --git a/docs/README.md b/docs/README.md index 3c09ca6..3eb5c02 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ -# PhysioMotion4D Documentation +# PhysioTwin4D Documentation -This directory contains the source files for PhysioMotion4D's documentation, which is built using [Sphinx](https://www.sphinx-doc.org/) and hosted on [ReadTheDocs](https://readthedocs.org/). +This directory contains the source files for PhysioTwin4D's documentation, which is built using [Sphinx](https://www.sphinx-doc.org/) and hosted on [ReadTheDocs](https://readthedocs.org/). ## Recently Updated! diff --git a/docs/_static/custom.css b/docs/_static/custom.css index 69f6eb8..08b5b5d 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -1,5 +1,5 @@ /* ============================================ - PhysioMotion4D - Documentation Style + PhysioTwin4D - Documentation Style ============================================ */ /* ==================== ROOT VARIABLES ==================== */ @@ -13,12 +13,12 @@ --radius-sm: 0.25rem; --radius-md: 0.375rem; --nvidia-green: #76b900; - --pm4d-ink: #111111; - --pm4d-charcoal: #1a1a1a; - --pm4d-muted: #5f6670; - --pm4d-line: #d9dee6; - --pm4d-surface: #ffffff; - --pm4d-page: #f4f6f8; + --pt4d-ink: #111111; + --pt4d-charcoal: #1a1a1a; + --pt4d-muted: #5f6670; + --pt4d-line: #d9dee6; + --pt4d-surface: #ffffff; + --pt4d-page: #f4f6f8; } /* ==================== GLOBAL STYLES ==================== */ @@ -26,8 +26,8 @@ /* Improved Typography - minimal override */ body { line-height: 1.6; - background: var(--pm4d-page); - color: var(--pm4d-ink); + background: var(--pt4d-page); + color: var(--pt4d-ink); } /* Smooth Scrolling */ @@ -45,7 +45,7 @@ h4, h5, h6 { line-height: 1.3; - color: var(--pm4d-ink); + color: var(--pt4d-ink); } /* ==================== LINKS ==================== */ @@ -91,7 +91,7 @@ table { } .wy-side-nav-search { - background: var(--pm4d-ink); + background: var(--pt4d-ink); border-bottom: 3px solid var(--nvidia-green); } @@ -108,7 +108,7 @@ table { } .wy-nav-side { - background: var(--pm4d-charcoal); + background: var(--pt4d-charcoal); } .wy-menu-vertical header, @@ -130,7 +130,7 @@ table { /* Use default content area styling */ .wy-nav-content { max-width: 1200px; - background: var(--pm4d-surface); + background: var(--pt4d-surface); } /* ==================== BUTTONS ==================== */ @@ -237,7 +237,7 @@ dt.sig { /* ==================== NVIDIA-STYLE TUTORIAL LANDING ==================== */ -.pm4d-hero { +.pt4d-hero { margin: -1.618em -3.236em 2rem; padding: 4rem 3.236em 4.5rem; color: #ffffff; @@ -245,13 +245,13 @@ dt.sig { border-bottom: 6px solid var(--nvidia-green); } -.pm4d-hero__brand img { +.pt4d-hero__brand img { width: 150px; border-radius: 0; margin-bottom: 1.5rem; } -.pm4d-kicker { +.pt4d-kicker { margin: 0 0 0.75rem; color: var(--nvidia-green); font-size: 0.85rem; @@ -260,7 +260,7 @@ dt.sig { text-transform: uppercase; } -.pm4d-hero h1 { +.pt4d-hero h1 { max-width: 780px; margin: 0 0 1rem; color: #ffffff; @@ -268,14 +268,14 @@ dt.sig { line-height: 1.08; } -.pm4d-hero p:not(.pm4d-kicker):not(.pm4d-hero__version) { +.pt4d-hero p:not(.pt4d-kicker):not(.pt4d-hero__version) { max-width: 760px; margin: 0; color: #d8dde6; font-size: 1.1rem; } -.pm4d-hero p.pm4d-hero__version { +.pt4d-hero p.pt4d-hero__version { max-width: 760px; margin: 1.9rem 0 0; color: #ffffff; @@ -283,7 +283,7 @@ dt.sig { font-weight: 700; } -.pm4d-card-grid { +.pt4d-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.15rem; @@ -292,7 +292,7 @@ dt.sig { z-index: 2; } -.pm4d-clinical-notice { +.pt4d-clinical-notice { margin: -3.5rem 0 2rem; padding: 1rem 1.25rem; position: relative; @@ -305,20 +305,20 @@ dt.sig { box-shadow: 0 12px 28px rgba(17, 17, 17, 0.14); } -.pm4d-clinical-notice strong { +.pt4d-clinical-notice strong { display: block; margin-bottom: 0.25rem; } -.pm4d-card, -.pm4d-card:visited { +.pt4d-card, +.pt4d-card:visited { display: flex; min-height: 214px; padding: 1.25rem; - color: var(--pm4d-ink); + color: var(--pt4d-ink); text-decoration: none; background: #ffffff; - border: 1px solid var(--pm4d-line); + border: 1px solid var(--pt4d-line); border-top: 4px solid var(--nvidia-green); border-radius: 8px; box-shadow: 0 16px 34px rgba(17, 17, 17, 0.16); @@ -326,16 +326,16 @@ dt.sig { transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease; } -.pm4d-card:hover { - color: var(--pm4d-ink); +.pt4d-card:hover { + color: var(--pt4d-ink); text-decoration: none; border-color: var(--nvidia-green); box-shadow: 0 20px 42px rgba(17, 17, 17, 0.22); transform: translateY(-4px); } -.pm4d-card:focus-visible { - color: var(--pm4d-ink); +.pt4d-card:focus-visible { + color: var(--pt4d-ink); text-decoration: none; border-color: var(--nvidia-green); outline: 3px solid #111111; @@ -343,80 +343,80 @@ dt.sig { box-shadow: 0 0 0 5px rgba(118, 185, 0, 0.35); } -.pm4d-card__number { +.pt4d-card__number { color: var(--nvidia-green); font-size: 0.82rem; font-weight: 800; letter-spacing: 0.12em; } -.pm4d-card h2 { +.pt4d-card h2 { margin: 0.55rem 0 0.65rem; - color: var(--pm4d-ink); + color: var(--pt4d-ink); font-size: 1.18rem; line-height: 1.2; } -.pm4d-card p { +.pt4d-card p { margin: 0 0 1rem; - color: var(--pm4d-muted); + color: var(--pt4d-muted); font-size: 0.95rem; line-height: 1.5; } -.pm4d-card__meta { +.pt4d-card__meta { margin-top: auto; - color: var(--pm4d-ink); + color: var(--pt4d-ink); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; } -.pm4d-topic-section { +.pt4d-topic-section { margin: 2.5rem 0 2.75rem; } -.pm4d-section-heading { +.pt4d-section-heading { margin-bottom: 1.25rem; } -.pm4d-section-heading h2 { +.pt4d-section-heading h2 { margin: 0; font-size: 1.75rem; } -.pm4d-topic-grid { +.pt4d-topic-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; } -.pm4d-topic-card, -.pm4d-topic-card:visited { +.pt4d-topic-card, +.pt4d-topic-card:visited { display: block; min-height: 158px; padding: 1.15rem; - color: var(--pm4d-ink); + color: var(--pt4d-ink); text-decoration: none; background: #ffffff; - border: 1px solid var(--pm4d-line); + border: 1px solid var(--pt4d-line); border-left: 4px solid var(--nvidia-green); border-radius: 8px; box-shadow: 0 8px 20px rgba(17, 17, 17, 0.08); transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease; } -.pm4d-topic-card:hover { - color: var(--pm4d-ink); +.pt4d-topic-card:hover { + color: var(--pt4d-ink); text-decoration: none; border-color: var(--nvidia-green); box-shadow: 0 12px 26px rgba(17, 17, 17, 0.14); transform: translateY(-3px); } -.pm4d-topic-card:focus-visible { - color: var(--pm4d-ink); +.pt4d-topic-card:focus-visible { + color: var(--pt4d-ink); text-decoration: none; border-color: var(--nvidia-green); outline: 3px solid #111111; @@ -424,29 +424,29 @@ dt.sig { box-shadow: 0 0 0 5px rgba(118, 185, 0, 0.35); } -.pm4d-topic-card h3 { +.pt4d-topic-card h3 { margin: 0 0 0.6rem; font-size: 1.05rem; } -.pm4d-topic-card p { +.pt4d-topic-card p { margin: 0; - color: var(--pm4d-muted); + color: var(--pt4d-muted); font-size: 0.92rem; line-height: 1.5; } @media screen and (max-width: 768px) { - .pm4d-hero { + .pt4d-hero { margin: -1.618em -1.618em 2rem; padding: 3rem 1.618em 4.25rem; } - .pm4d-hero h1 { + .pt4d-hero h1 { font-size: 2rem; } - .pm4d-card-grid { + .pt4d-card-grid { grid-template-columns: 1fr; } } diff --git a/docs/api/base.rst b/docs/api/base.rst index 2df904a..0a90a54 100644 --- a/docs/api/base.rst +++ b/docs/api/base.rst @@ -2,16 +2,16 @@ Base Class ==================================== -.. module:: physiomotion4d.physiomotion4d_base -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.physiotwin4d_base +.. currentmodule:: physiotwin4d -``PhysioMotion4DBase`` provides the shared logging behavior used by workflow, +``PhysioTwin4DBase`` provides the shared logging behavior used by workflow, segmentation, registration, transform, contour, and USD helper classes. Class Reference =============== -.. autoclass:: PhysioMotion4DBase +.. autoclass:: PhysioTwin4DBase :members: :undoc-members: :show-inheritance: @@ -27,9 +27,9 @@ global log filtering by class name. import logging - from physiomotion4d import PhysioMotion4DBase + from physiotwin4d import PhysioTwin4DBase - class MyProcessor(PhysioMotion4DBase): + class MyProcessor(PhysioTwin4DBase): def __init__(self) -> None: super().__init__(class_name="MyProcessor", log_level=logging.INFO) @@ -41,13 +41,13 @@ global log filtering by class name. processor = MyProcessor() processor.process() - PhysioMotion4DBase.set_log_classes(["MyProcessor"]) - PhysioMotion4DBase.set_log_all_classes() + PhysioTwin4DBase.set_log_classes(["MyProcessor"]) + PhysioTwin4DBase.set_log_all_classes() Extension Notes =============== -New runtime classes should inherit from ``PhysioMotion4DBase`` and pass a +New runtime classes should inherit from ``PhysioTwin4DBase`` and pass a ``class_name`` plus ``log_level`` to ``super().__init__``. Standalone scripts, data containers, and small pure utility functions do not need to inherit from the base class. diff --git a/docs/api/cli/convert_image_to_usd.rst b/docs/api/cli/convert_image_to_usd.rst index 033f8ae..39764cc 100644 --- a/docs/api/cli/convert_image_to_usd.rst +++ b/docs/api/cli/convert_image_to_usd.rst @@ -2,7 +2,7 @@ convert_image_to_usd (CLI) ========================== -.. automodule:: physiomotion4d.cli.convert_image_to_usd +.. automodule:: physiotwin4d.cli.convert_image_to_usd :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/convert_image_to_vtk.rst b/docs/api/cli/convert_image_to_vtk.rst index c132590..b9959ce 100644 --- a/docs/api/cli/convert_image_to_vtk.rst +++ b/docs/api/cli/convert_image_to_vtk.rst @@ -2,7 +2,7 @@ convert_image_to_vtk (CLI) ========================== -.. automodule:: physiomotion4d.cli.convert_image_to_vtk +.. automodule:: physiotwin4d.cli.convert_image_to_vtk :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/convert_vtk_to_usd.rst b/docs/api/cli/convert_vtk_to_usd.rst index cd663da..cd39ad6 100644 --- a/docs/api/cli/convert_vtk_to_usd.rst +++ b/docs/api/cli/convert_vtk_to_usd.rst @@ -2,7 +2,7 @@ convert_vtk_to_usd (CLI) ======================== -.. automodule:: physiomotion4d.cli.convert_vtk_to_usd +.. automodule:: physiotwin4d.cli.convert_vtk_to_usd :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/create_statistical_model.rst b/docs/api/cli/create_statistical_model.rst index f56efce..7754b3f 100644 --- a/docs/api/cli/create_statistical_model.rst +++ b/docs/api/cli/create_statistical_model.rst @@ -2,7 +2,7 @@ create_statistical_model (CLI) ============================== -.. automodule:: physiomotion4d.cli.create_statistical_model +.. automodule:: physiotwin4d.cli.create_statistical_model :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/download_data.rst b/docs/api/cli/download_data.rst index 409c1c5..9a15cdd 100644 --- a/docs/api/cli/download_data.rst +++ b/docs/api/cli/download_data.rst @@ -2,7 +2,7 @@ download_data (CLI) =================== -.. automodule:: physiomotion4d.cli.download_data +.. automodule:: physiotwin4d.cli.download_data :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/fit_statistical_model_to_patient.rst b/docs/api/cli/fit_statistical_model_to_patient.rst index 16a9338..c12e060 100644 --- a/docs/api/cli/fit_statistical_model_to_patient.rst +++ b/docs/api/cli/fit_statistical_model_to_patient.rst @@ -2,7 +2,7 @@ fit_statistical_model_to_patient (CLI) ====================================== -.. automodule:: physiomotion4d.cli.fit_statistical_model_to_patient +.. automodule:: physiotwin4d.cli.fit_statistical_model_to_patient :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/index.rst b/docs/api/cli/index.rst index b6440d1..eb4657d 100644 --- a/docs/api/cli/index.rst +++ b/docs/api/cli/index.rst @@ -2,11 +2,11 @@ CLI Entry-Point API ==================== -.. module:: physiomotion4d.cli -.. currentmodule:: physiomotion4d.cli +.. module:: physiotwin4d.cli +.. currentmodule:: physiotwin4d.cli -The ``physiomotion4d.cli`` subpackage contains the entry-point scripts that -back the installed ``physiomotion4d-*`` console commands. Each module exposes +The ``physiotwin4d.cli`` subpackage contains the entry-point scripts that +back the installed ``physiotwin4d-*`` console commands. Each module exposes a ``main()`` function that parses ``argparse`` arguments and dispatches into the corresponding workflow class. diff --git a/docs/api/cli/reconstruct_highres_4d_ct.rst b/docs/api/cli/reconstruct_highres_4d_ct.rst index 7072fd4..b05b29c 100644 --- a/docs/api/cli/reconstruct_highres_4d_ct.rst +++ b/docs/api/cli/reconstruct_highres_4d_ct.rst @@ -2,7 +2,7 @@ reconstruct_highres_4d_ct (CLI) =============================== -.. automodule:: physiomotion4d.cli.reconstruct_highres_4d_ct +.. automodule:: physiotwin4d.cli.reconstruct_highres_4d_ct :members: :undoc-members: :show-inheritance: diff --git a/docs/api/cli/visualize_pca_modes.rst b/docs/api/cli/visualize_pca_modes.rst index 7bf270a..9394b5f 100644 --- a/docs/api/cli/visualize_pca_modes.rst +++ b/docs/api/cli/visualize_pca_modes.rst @@ -2,7 +2,7 @@ visualize_pca_modes (CLI) ========================= -.. automodule:: physiomotion4d.cli.visualize_pca_modes +.. automodule:: physiotwin4d.cli.visualize_pca_modes :members: :undoc-members: :show-inheritance: diff --git a/docs/api/index.rst b/docs/api/index.rst index a3909bd..548e9d1 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -2,9 +2,9 @@ API Reference ==================== -Complete API documentation for PhysioMotion4D modules. +Complete API documentation for PhysioTwin4D modules. -This section provides detailed documentation for all PhysioMotion4D classes, functions, and modules organized by functionality. +This section provides detailed documentation for all PhysioTwin4D classes, functions, and modules organized by functionality. .. toctree:: :maxdepth: 2 @@ -26,34 +26,34 @@ By Category ----------- **Core Classes** - * :class:`~physiomotion4d.PhysioMotion4DBase` - Base class for all components + * :class:`~physiotwin4d.PhysioTwin4DBase` - Base class for all components **Workflows** - * :class:`~physiomotion4d.WorkflowConvertImageToUSD` - Heart CT to USD - * :class:`~physiomotion4d.WorkflowCreateStatisticalModel` - Create PCA statistical shape model - * :class:`~physiomotion4d.WorkflowFitStatisticalModelToPatient` - Heart model registration + * :class:`~physiotwin4d.WorkflowConvertImageToUSD` - Heart CT to USD + * :class:`~physiotwin4d.WorkflowCreateStatisticalModel` - Create PCA statistical shape model + * :class:`~physiotwin4d.WorkflowFitStatisticalModelToPatient` - Heart model registration **Segmentation** - * :class:`~physiomotion4d.SegmentAnatomyBase` - Base segmentation class - * :class:`~physiomotion4d.SegmentChestTotalSegmentator` - TotalSegmentator - * :class:`~physiomotion4d.SegmentHeartSimpleware` - Simpleware cardiac segmentation + * :class:`~physiotwin4d.SegmentAnatomyBase` - Base segmentation class + * :class:`~physiotwin4d.SegmentChestTotalSegmentator` - TotalSegmentator + * :class:`~physiotwin4d.SegmentHeartSimpleware` - Simpleware cardiac segmentation **Image Registration** - * :class:`~physiomotion4d.RegisterImagesBase` - Base registration class - * :class:`~physiomotion4d.RegisterImagesANTS` - ANTs registration - * :class:`~physiomotion4d.RegisterImagesICON` - Icon deep learning registration - * :class:`~physiomotion4d.RegisterTimeSeriesImages` - 4D time series registration + * :class:`~physiotwin4d.RegisterImagesBase` - Base registration class + * :class:`~physiotwin4d.RegisterImagesANTS` - ANTs registration + * :class:`~physiotwin4d.RegisterImagesICON` - Icon deep learning registration + * :class:`~physiotwin4d.RegisterTimeSeriesImages` - 4D time series registration **Model Registration** - * :class:`~physiomotion4d.RegisterModelsICP` - Iterative Closest Point - * :class:`~physiomotion4d.RegisterModelsICPITK` - ICP with ITK - * :class:`~physiomotion4d.RegisterModelsDistanceMaps` - Distance map-based - * :class:`~physiomotion4d.RegisterModelsPCA` - PCA-based registration + * :class:`~physiotwin4d.RegisterModelsICP` - Iterative Closest Point + * :class:`~physiotwin4d.RegisterModelsICPITK` - ICP with ITK + * :class:`~physiotwin4d.RegisterModelsDistanceMaps` - Distance map-based + * :class:`~physiotwin4d.RegisterModelsPCA` - PCA-based registration **USD Tools** - * :mod:`~physiomotion4d.usd_tools` - USD file utilities - * :mod:`~physiomotion4d.usd_anatomy_tools` - Anatomical structure tools - * :class:`~physiomotion4d.ConvertVTKToUSD` - VTK to USD conversion + * :mod:`~physiotwin4d.usd_tools` - USD file utilities + * :mod:`~physiotwin4d.usd_anatomy_tools` - Anatomical structure tools + * :class:`~physiotwin4d.ConvertVTKToUSD` - VTK to USD conversion Module Index ============ diff --git a/docs/api/model_registration/distance_maps.rst b/docs/api/model_registration/distance_maps.rst index efdfdd8..3b25a0f 100644 --- a/docs/api/model_registration/distance_maps.rst +++ b/docs/api/model_registration/distance_maps.rst @@ -2,8 +2,8 @@ Distance Map Registration ==================================== -.. module:: physiomotion4d.register_models_distance_maps -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_models_distance_maps +.. currentmodule:: physiotwin4d Register models using distance field optimization. diff --git a/docs/api/model_registration/icp.rst b/docs/api/model_registration/icp.rst index b10ecf1..ddffd9a 100644 --- a/docs/api/model_registration/icp.rst +++ b/docs/api/model_registration/icp.rst @@ -2,8 +2,8 @@ ICP (Iterative Closest Point) ==================================== -.. module:: physiomotion4d.register_models_icp -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_models_icp +.. currentmodule:: physiotwin4d Pure Python implementation of Iterative Closest Point registration. diff --git a/docs/api/model_registration/icp_itk.rst b/docs/api/model_registration/icp_itk.rst index 39bc20e..570eff3 100644 --- a/docs/api/model_registration/icp_itk.rst +++ b/docs/api/model_registration/icp_itk.rst @@ -2,8 +2,8 @@ ICP with ITK Backend ==================================== -.. module:: physiomotion4d.register_models_icp_itk -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_models_icp_itk +.. currentmodule:: physiotwin4d ICP registration using ITK's optimized implementation. diff --git a/docs/api/model_registration/index.rst b/docs/api/model_registration/index.rst index b30d46f..456aed3 100644 --- a/docs/api/model_registration/index.rst +++ b/docs/api/model_registration/index.rst @@ -2,7 +2,7 @@ Model Registration Modules ========================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Model registration classes align PyVista meshes and derived image masks. They are used by :class:`WorkflowFitStatisticalModelToPatient`. @@ -34,7 +34,7 @@ Most users should access model registration through the workflow: import itk import pyvista as pv - from physiomotion4d import WorkflowFitStatisticalModelToPatient + from physiotwin4d import WorkflowFitStatisticalModelToPatient workflow = WorkflowFitStatisticalModelToPatient( template_model=pv.read("template_heart.vtu"), diff --git a/docs/api/model_registration/pca.rst b/docs/api/model_registration/pca.rst index c8512a7..0f5a7ab 100644 --- a/docs/api/model_registration/pca.rst +++ b/docs/api/model_registration/pca.rst @@ -2,8 +2,8 @@ PCA-Based Registration ==================================== -.. module:: physiomotion4d.register_models_pca -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_models_pca +.. currentmodule:: physiotwin4d Shape-based registration using principal component analysis. diff --git a/docs/api/registration/ants.rst b/docs/api/registration/ants.rst index 721707d..2fa77f8 100644 --- a/docs/api/registration/ants.rst +++ b/docs/api/registration/ants.rst @@ -2,8 +2,8 @@ ANTs Registration ================= -.. module:: physiomotion4d.register_images_ants -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_images_ants +.. currentmodule:: physiotwin4d ``RegisterImagesANTS`` provides optimization-based deformable image registration through ANTs. @@ -23,7 +23,7 @@ Basic Registration import itk - from physiomotion4d import RegisterImagesANTS + from physiotwin4d import RegisterImagesANTS fixed = itk.imread("reference.mha") moving = itk.imread("moving.mha") diff --git a/docs/api/registration/base.rst b/docs/api/registration/base.rst index 055cbbb..41fda34 100644 --- a/docs/api/registration/base.rst +++ b/docs/api/registration/base.rst @@ -2,8 +2,8 @@ Registration Base Class ==================================== -.. module:: physiomotion4d.register_images_base -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_images_base +.. currentmodule:: physiotwin4d Abstract base class for all image registration methods. diff --git a/docs/api/registration/greedy.rst b/docs/api/registration/greedy.rst index 3dcb989..230ffe5 100644 --- a/docs/api/registration/greedy.rst +++ b/docs/api/registration/greedy.rst @@ -2,8 +2,8 @@ Greedy Registration =================== -.. module:: physiomotion4d.register_images_greedy -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_images_greedy +.. currentmodule:: physiotwin4d ``RegisterImagesGreedy`` provides fast CPU-based deformable image registration using the PICSL Greedy backend. @@ -23,7 +23,7 @@ Basic Registration import itk - from physiomotion4d import RegisterImagesGreedy + from physiotwin4d import RegisterImagesGreedy fixed = itk.imread("reference.mha") moving = itk.imread("moving.mha") diff --git a/docs/api/registration/icon.rst b/docs/api/registration/icon.rst index 38bd4ba..f8f2141 100644 --- a/docs/api/registration/icon.rst +++ b/docs/api/registration/icon.rst @@ -2,8 +2,8 @@ ICON Image Registration ================================ -.. module:: physiomotion4d.register_images_icon -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_images_icon +.. currentmodule:: physiotwin4d ``RegisterImagesICON`` performs deformable image registration using the uniGradICON registration backend. @@ -23,7 +23,7 @@ Basic Registration import itk - from physiomotion4d import RegisterImagesICON + from physiotwin4d import RegisterImagesICON fixed = itk.imread("reference_frame.mha") moving = itk.imread("moving_frame.mha") diff --git a/docs/api/registration/index.rst b/docs/api/registration/index.rst index 08e7126..50ba89c 100644 --- a/docs/api/registration/index.rst +++ b/docs/api/registration/index.rst @@ -2,9 +2,9 @@ Image Registration Modules ========================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d -PhysioMotion4D image registration classes align moving 3D images to a fixed +PhysioTwin4D image registration classes align moving 3D images to a fixed 3D image and return transform dictionaries. .. toctree:: @@ -35,7 +35,7 @@ Basic Example import itk - from physiomotion4d import RegisterImagesANTS + from physiotwin4d import RegisterImagesANTS fixed = itk.imread("reference.mha") moving = itk.imread("moving.mha") diff --git a/docs/api/registration/time_series.rst b/docs/api/registration/time_series.rst index e903ea6..f6c391d 100644 --- a/docs/api/registration/time_series.rst +++ b/docs/api/registration/time_series.rst @@ -2,8 +2,8 @@ Time-Series Registration ======================== -.. module:: physiomotion4d.register_time_series_images -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.register_time_series_images +.. currentmodule:: physiotwin4d ``RegisterTimeSeriesImages`` registers ordered 3D image phases to a reference frame using a caller-supplied :class:`RegisterImagesBase` backend (e.g. @@ -26,7 +26,7 @@ Basic Usage import itk - from physiomotion4d import RegisterImagesGreedy, RegisterTimeSeriesImages + from physiotwin4d import RegisterImagesGreedy, RegisterTimeSeriesImages images = [itk.imread(f"phase_{idx:02d}.mha") for idx in range(10)] diff --git a/docs/api/segmentation/base.rst b/docs/api/segmentation/base.rst index 66309e0..2fc2d97 100644 --- a/docs/api/segmentation/base.rst +++ b/docs/api/segmentation/base.rst @@ -2,11 +2,11 @@ Segmentation Base Class ======================== -.. module:: physiomotion4d.segment_anatomy_base -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.segment_anatomy_base +.. currentmodule:: physiotwin4d ``SegmentAnatomyBase`` defines the shared chest-anatomy segmentation contract -used by PhysioMotion4D segmentation implementations. It owns an +used by PhysioTwin4D segmentation implementations. It owns an :class:`AnatomyTaxonomy` instance that subclasses populate to declare which anatomy groups (and which organ labels within each group) they produce. @@ -27,7 +27,7 @@ Concrete segmenters accept an ITK image and return a dictionary of ITK images: import itk - from physiomotion4d import SegmentChestTotalSegmentator + from physiotwin4d import SegmentChestTotalSegmentator image = itk.imread("chest_ct.nrrd") segmenter = SegmentChestTotalSegmentator() @@ -91,7 +91,7 @@ Extending Segmentation New runtime segmentation classes should: -1. Inherit from :class:`SegmentAnatomyBase` (or another :class:`PhysioMotion4DBase` +1. Inherit from :class:`SegmentAnatomyBase` (or another :class:`PhysioTwin4DBase` subclass if no anatomy taxonomy is needed). 2. Populate ``self.taxonomy`` with ``add_organ`` calls in ``__init__``. 3. Call ``self._finalize_other_group()`` once all groups have been registered. diff --git a/docs/api/segmentation/index.rst b/docs/api/segmentation/index.rst index 6c74902..51b647a 100644 --- a/docs/api/segmentation/index.rst +++ b/docs/api/segmentation/index.rst @@ -2,14 +2,14 @@ Segmentation Modules ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d AI-powered anatomical structure identification from medical images using state-of-the-art deep learning models. Overview ======== -PhysioMotion4D supports multiple segmentation approaches: +PhysioTwin4D supports multiple segmentation approaches: * **TotalSegmentator**: Whole-body CT segmentation (100+ structures) * **Simpleware**: Cardiac-focused segmentation (requires Simpleware Medical) @@ -43,7 +43,7 @@ Basic Segmentation .. code-block:: python - from physiomotion4d import SegmentChestTotalSegmentator + from physiotwin4d import SegmentChestTotalSegmentator segmenter = SegmentChestTotalSegmentator() result = segmenter.segment(ct_image) diff --git a/docs/api/segmentation/simpleware.rst b/docs/api/segmentation/simpleware.rst index 0ee5889..021c6e7 100644 --- a/docs/api/segmentation/simpleware.rst +++ b/docs/api/segmentation/simpleware.rst @@ -2,8 +2,8 @@ Simpleware Heart Segmenter ========================== -.. module:: physiomotion4d.segment_heart_simpleware -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.segment_heart_simpleware +.. currentmodule:: physiotwin4d ``SegmentHeartSimpleware`` runs Synopsys Simpleware Medical's ASCardio module as an external process and returns the resulting heart and major-vessel masks @@ -24,7 +24,7 @@ Basic Usage import itk - from physiomotion4d import SegmentHeartSimpleware + from physiotwin4d import SegmentHeartSimpleware image = itk.imread("chest_ct.nrrd") segmenter = SegmentHeartSimpleware() diff --git a/docs/api/segmentation/totalsegmentator.rst b/docs/api/segmentation/totalsegmentator.rst index 66db952..fff0c0c 100644 --- a/docs/api/segmentation/totalsegmentator.rst +++ b/docs/api/segmentation/totalsegmentator.rst @@ -2,11 +2,11 @@ TotalSegmentator ================ -.. module:: physiomotion4d.segment_chest_total_segmentator -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.segment_chest_total_segmentator +.. currentmodule:: physiotwin4d ``SegmentChestTotalSegmentator`` groups a TotalSegmentator labelmap into the -anatomy masks used by PhysioMotion4D workflows. +anatomy masks used by PhysioTwin4D workflows. Class Reference =============== @@ -23,7 +23,7 @@ Basic Usage import itk - from physiomotion4d import SegmentChestTotalSegmentator + from physiotwin4d import SegmentChestTotalSegmentator image = itk.imread("chest_ct.nrrd") segmenter = SegmentChestTotalSegmentator() @@ -69,7 +69,7 @@ returned dictionary and exposes a ``contrast_threshold`` attribute .. code-block:: python - from physiomotion4d import SegmentChestTotalSegmentatorWithContrast + from physiotwin4d import SegmentChestTotalSegmentatorWithContrast segmenter = SegmentChestTotalSegmentatorWithContrast() segmenter.contrast_threshold = 600 # optional override @@ -82,7 +82,7 @@ Operational Notes TotalSegmentator model inference may download model assets and can be slow on a CPU-only environment. For repeatable workflows, prefer the tutorial scripts or -the ``physiomotion4d-convert-image-to-vtk`` CLI. +the ``physiotwin4d-convert-image-to-vtk`` CLI. See Also ======== diff --git a/docs/api/usd/anatomy_tools.rst b/docs/api/usd/anatomy_tools.rst index 589a54c..89bb997 100644 --- a/docs/api/usd/anatomy_tools.rst +++ b/docs/api/usd/anatomy_tools.rst @@ -2,14 +2,14 @@ USD Anatomy Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Specialized tools for anatomical structure handling in USD. Module Reference ================ -.. automodule:: physiomotion4d.usd_anatomy_tools +.. automodule:: physiotwin4d.usd_anatomy_tools :members: :undoc-members: diff --git a/docs/api/usd/index.rst b/docs/api/usd/index.rst index d09a968..5f93d09 100644 --- a/docs/api/usd/index.rst +++ b/docs/api/usd/index.rst @@ -2,7 +2,7 @@ USD Generation Modules ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Convert medical imaging data to Universal Scene Description (USD) format for NVIDIA Omniverse. @@ -43,7 +43,7 @@ Convert VTK to USD .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD converter = ConvertVTKToUSD.from_files( data_basename="Heart", @@ -57,7 +57,7 @@ Create Anatomical Scene .. code-block:: python - from physiomotion4d import usd_anatomy_tools + from physiotwin4d import usd_anatomy_tools stage = usd_anatomy_tools.create_anatomical_stage() usd_anatomy_tools.add_heart_model(stage, "heart.vtk") diff --git a/docs/api/usd/tools.rst b/docs/api/usd/tools.rst index ad54e87..58cf064 100644 --- a/docs/api/usd/tools.rst +++ b/docs/api/usd/tools.rst @@ -2,14 +2,14 @@ USD Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Core utilities for USD file creation and manipulation. Module Reference ================ -.. automodule:: physiomotion4d.usd_tools +.. automodule:: physiotwin4d.usd_tools :members: :undoc-members: diff --git a/docs/api/usd/vtk_conversion.rst b/docs/api/usd/vtk_conversion.rst index 32f8f58..3dfbdd5 100644 --- a/docs/api/usd/vtk_conversion.rst +++ b/docs/api/usd/vtk_conversion.rst @@ -2,8 +2,8 @@ VTK to USD Conversion ==================================== -.. module:: physiomotion4d.convert_vtk_to_usd -.. currentmodule:: physiomotion4d +.. module:: physiotwin4d.convert_vtk_to_usd +.. currentmodule:: physiotwin4d Convert VTK mesh files to USD format with animation support. diff --git a/docs/api/usd/vtk_to_usd_lib.rst b/docs/api/usd/vtk_to_usd_lib.rst index 4bddc4e..901b4d9 100644 --- a/docs/api/usd/vtk_to_usd_lib.rst +++ b/docs/api/usd/vtk_to_usd_lib.rst @@ -2,12 +2,12 @@ Low-Level vtk_to_usd Subpackage =============================== -.. module:: physiomotion4d.vtk_to_usd -.. currentmodule:: physiomotion4d.vtk_to_usd +.. module:: physiotwin4d.vtk_to_usd +.. currentmodule:: physiotwin4d.vtk_to_usd -``physiomotion4d.vtk_to_usd`` is a stable low-level API for advanced external +``physiotwin4d.vtk_to_usd`` is a stable low-level API for advanced external users. Inside this repository (experiments, workflows, CLIs, tutorials, -tests), use :class:`~physiomotion4d.ConvertVTKToUSD` from +tests), use :class:`~physiotwin4d.ConvertVTKToUSD` from :doc:`vtk_conversion` instead of importing this subpackage directly. This subpackage exposes the readers, data containers, coordinate helpers, and @@ -18,7 +18,7 @@ for convenience. File Facade =========== -.. automodule:: physiomotion4d.vtk_to_usd.converter +.. automodule:: physiotwin4d.vtk_to_usd.converter :members: :undoc-members: :show-inheritance: @@ -26,7 +26,7 @@ File Facade Data Structures =============== -.. automodule:: physiomotion4d.vtk_to_usd.data_structures +.. automodule:: physiotwin4d.vtk_to_usd.data_structures :members: :undoc-members: :show-inheritance: @@ -34,7 +34,7 @@ Data Structures VTK Readers =========== -.. automodule:: physiomotion4d.vtk_to_usd.vtk_reader +.. automodule:: physiotwin4d.vtk_to_usd.vtk_reader :members: :undoc-members: :show-inheritance: @@ -42,7 +42,7 @@ VTK Readers USD Mesh Conversion =================== -.. automodule:: physiomotion4d.vtk_to_usd.usd_mesh_converter +.. automodule:: physiotwin4d.vtk_to_usd.usd_mesh_converter :members: :undoc-members: :show-inheritance: @@ -50,7 +50,7 @@ USD Mesh Conversion Material Manager ================ -.. automodule:: physiomotion4d.vtk_to_usd.material_manager +.. automodule:: physiotwin4d.vtk_to_usd.material_manager :members: :undoc-members: :show-inheritance: @@ -58,7 +58,7 @@ Material Manager Mesh Utilities ============== -.. automodule:: physiomotion4d.vtk_to_usd.mesh_utils +.. automodule:: physiotwin4d.vtk_to_usd.mesh_utils :members: :undoc-members: :show-inheritance: @@ -66,7 +66,7 @@ Mesh Utilities USD Coordinate and Primvar Helpers ================================== -.. automodule:: physiomotion4d.vtk_to_usd.usd_utils +.. automodule:: physiotwin4d.vtk_to_usd.usd_utils :members: :undoc-members: :show-inheritance: @@ -74,7 +74,7 @@ USD Coordinate and Primvar Helpers Primvar Derivations =================== -.. automodule:: physiomotion4d.vtk_to_usd.primvar_derivations +.. automodule:: physiotwin4d.vtk_to_usd.primvar_derivations :members: :undoc-members: :show-inheritance: diff --git a/docs/api/utilities/contour_tools.rst b/docs/api/utilities/contour_tools.rst index 3e4b881..8879c63 100644 --- a/docs/api/utilities/contour_tools.rst +++ b/docs/api/utilities/contour_tools.rst @@ -2,14 +2,14 @@ Contour Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Contour extraction and processing utilities. Module Reference ================ -.. automodule:: physiomotion4d.contour_tools +.. automodule:: physiotwin4d.contour_tools :members: :undoc-members: diff --git a/docs/api/utilities/data_download.rst b/docs/api/utilities/data_download.rst index a84be55..e877a02 100644 --- a/docs/api/utilities/data_download.rst +++ b/docs/api/utilities/data_download.rst @@ -2,7 +2,7 @@ Data Downloads ============== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Helpers for downloading and verifying optional example datasets used by the tutorials and experiments. @@ -10,7 +10,7 @@ tutorials and experiments. Module Reference ================ -.. automodule:: physiomotion4d.data_download_tools +.. automodule:: physiotwin4d.data_download_tools :members: :undoc-members: :show-inheritance: diff --git a/docs/api/utilities/image_conversion.rst b/docs/api/utilities/image_conversion.rst index b90ac1e..758bcb2 100644 --- a/docs/api/utilities/image_conversion.rst +++ b/docs/api/utilities/image_conversion.rst @@ -2,7 +2,7 @@ 4D Image Conversion ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Utilities for converting 4D medical images into a 3D time-series sequence. ``.nrrd`` inputs (including Slicer ``.seq.nrrd`` heart sequences, whose @@ -13,7 +13,7 @@ with ``pynrrd``; all other formats (NIfTI ``.nii.gz``, MHA, …) are read with Module Reference ================ -.. automodule:: physiomotion4d.convert_image_4d_to_3d +.. automodule:: physiotwin4d.convert_image_4d_to_3d :members: :undoc-members: diff --git a/docs/api/utilities/image_tools.rst b/docs/api/utilities/image_tools.rst index a10369a..8fc4b95 100644 --- a/docs/api/utilities/image_tools.rst +++ b/docs/api/utilities/image_tools.rst @@ -2,14 +2,14 @@ Image Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Image I/O, preprocessing, and manipulation utilities. Module Reference ================ -.. automodule:: physiomotion4d.image_tools +.. automodule:: physiotwin4d.image_tools :members: :undoc-members: diff --git a/docs/api/utilities/index.rst b/docs/api/utilities/index.rst index 62277bb..d165a7c 100644 --- a/docs/api/utilities/index.rst +++ b/docs/api/utilities/index.rst @@ -2,7 +2,7 @@ Utility Modules ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Common utilities for image processing, transforms, and file handling. diff --git a/docs/api/utilities/labelmap_tools.rst b/docs/api/utilities/labelmap_tools.rst index 7b453b5..cd34f41 100644 --- a/docs/api/utilities/labelmap_tools.rst +++ b/docs/api/utilities/labelmap_tools.rst @@ -2,7 +2,7 @@ Labelmap Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Convert segmentation labelmaps into binary registration masks, with optional label exclusion and physically isotropic dilation. @@ -10,7 +10,7 @@ label exclusion and physically isotropic dilation. Module Reference ================ -.. automodule:: physiomotion4d.labelmap_tools +.. automodule:: physiotwin4d.labelmap_tools :members: :undoc-members: diff --git a/docs/api/utilities/test_tools.rst b/docs/api/utilities/test_tools.rst index 534da67..43b6f13 100644 --- a/docs/api/utilities/test_tools.rst +++ b/docs/api/utilities/test_tools.rst @@ -2,15 +2,15 @@ Test Tools ========== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d -Baseline vs. result image comparison utilities used by the PhysioMotion4D +Baseline vs. result image comparison utilities used by the PhysioTwin4D pytest suite. Module Reference ================ -.. automodule:: physiomotion4d.test_tools +.. automodule:: physiotwin4d.test_tools :members: :undoc-members: :show-inheritance: diff --git a/docs/api/utilities/transform_tools.rst b/docs/api/utilities/transform_tools.rst index e66a4ac..00a9471 100644 --- a/docs/api/utilities/transform_tools.rst +++ b/docs/api/utilities/transform_tools.rst @@ -2,14 +2,14 @@ Transform Tools ==================================== -.. currentmodule:: physiomotion4d +.. currentmodule:: physiotwin4d Coordinate transformation and image warping utilities. Module Reference ================ -.. automodule:: physiomotion4d.transform_tools +.. automodule:: physiotwin4d.transform_tools :members: :undoc-members: diff --git a/docs/api/workflows.rst b/docs/api/workflows.rst index e397cbc..50dcdaf 100644 --- a/docs/api/workflows.rst +++ b/docs/api/workflows.rst @@ -2,15 +2,15 @@ Workflow Classes ================ -.. module:: physiomotion4d.workflow_convert_image_to_usd -.. module:: physiomotion4d.workflow_convert_image_to_vtk -.. module:: physiomotion4d.workflow_convert_vtk_to_usd -.. module:: physiomotion4d.workflow_create_statistical_model -.. module:: physiomotion4d.workflow_fit_statistical_model_to_patient -.. module:: physiomotion4d.workflow_reconstruct_highres_4d_ct -.. currentmodule:: physiomotion4d - -Workflow classes are the highest-level Python API in PhysioMotion4D. They +.. module:: physiotwin4d.workflow_convert_image_to_usd +.. module:: physiotwin4d.workflow_convert_image_to_vtk +.. module:: physiotwin4d.workflow_convert_vtk_to_usd +.. module:: physiotwin4d.workflow_create_statistical_model +.. module:: physiotwin4d.workflow_fit_statistical_model_to_patient +.. module:: physiotwin4d.workflow_reconstruct_highres_4d_ct +.. currentmodule:: physiotwin4d + +Workflow classes are the highest-level Python API in PhysioTwin4D. They combine segmentation, registration, contour generation, and USD conversion into repeatable pipelines. The installed CLI commands are thin wrappers around these classes. @@ -48,7 +48,7 @@ Convert Image to USD .. code-block:: python - from physiomotion4d import ( + from physiotwin4d import ( RegisterImagesICON, SegmentChestTotalSegmentatorWithContrast, WorkflowConvertImageToUSD, @@ -76,7 +76,7 @@ Image to VTK import itk - from physiomotion4d import ( + from physiotwin4d import ( ContourTools, SegmentChestTotalSegmentatorWithContrast, WorkflowConvertImageToVTK, @@ -107,7 +107,7 @@ VTK to USD .. code-block:: python - from physiomotion4d import WorkflowConvertVTKToUSD + from physiotwin4d import WorkflowConvertVTKToUSD workflow = WorkflowConvertVTKToUSD( vtk_files=["heart_000.vtp", "heart_001.vtp"], @@ -136,7 +136,7 @@ Statistical Shape Modeling import itk import pyvista as pv - from physiomotion4d import WorkflowFitStatisticalModelToPatient + from physiotwin4d import WorkflowFitStatisticalModelToPatient workflow = WorkflowFitStatisticalModelToPatient( template_model=pv.read("template_heart.vtu"), @@ -158,7 +158,7 @@ High-Resolution 4D CT Reconstruction import itk - from physiomotion4d import RegisterImagesGreedyICON, WorkflowReconstructHighres4DCT + from physiotwin4d import RegisterImagesGreedyICON, WorkflowReconstructHighres4DCT time_series_images = [itk.imread(f"phase_{idx:02d}.mha") for idx in range(10)] workflow = WorkflowReconstructHighres4DCT( diff --git a/docs/architecture.rst b/docs/architecture.rst index 0400c05..e84e06a 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -2,14 +2,14 @@ Architecture ============ -PhysioMotion4D is organized around explicit workflow classes and smaller +PhysioTwin4D is organized around explicit workflow classes and smaller registration, segmentation, geometry, and USD utilities. Runtime workflow -classes inherit from :class:`PhysioMotion4DBase` for logging and common runtime +classes inherit from :class:`PhysioTwin4DBase` for logging and common runtime configuration. .. warning:: - PhysioMotion4D {{ pm4d_project_version }} beta is not validated for clinical + PhysioTwin4D {{ pt4d_project_version }} beta is not validated for clinical use. It is a research and visualization toolkit, not a medical device. Data Flow @@ -64,7 +64,7 @@ Primary Workflows ``WorkflowConvertVTKToUSD`` Converts VTK files to animated USD scenes through the supported workflow - wrapper. The lower-level :mod:`physiomotion4d.vtk_to_usd` package exposes + wrapper. The lower-level :mod:`physiotwin4d.vtk_to_usd` package exposes advanced file conversion primitives. Component Boundaries @@ -88,10 +88,10 @@ CLI Boundary The installed CLI commands in ``pyproject.toml`` are thin wrappers around the workflow classes. They are the preferred examples for executable API usage: -* ``physiomotion4d-convert-image-to-usd`` -* ``physiomotion4d-convert-image-to-vtk`` -* ``physiomotion4d-create-statistical-model`` -* ``physiomotion4d-fit-statistical-model-to-patient`` -* ``physiomotion4d-convert-vtk-to-usd`` -* ``physiomotion4d-reconstruct-highres-4d-ct`` -* ``physiomotion4d-visualize-pca-modes`` +* ``physiotwin4d-convert-image-to-usd`` +* ``physiotwin4d-convert-image-to-vtk`` +* ``physiotwin4d-create-statistical-model`` +* ``physiotwin4d-fit-statistical-model-to-patient`` +* ``physiotwin4d-convert-vtk-to-usd`` +* ``physiotwin4d-reconstruct-highres-4d-ct`` +* ``physiotwin4d-visualize-pca-modes`` diff --git a/docs/changelog.rst b/docs/changelog.rst index 7da29c3..031f89a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,10 +2,17 @@ Release Notes ============= +2026.07.0 Beta +============== + +PhysioTwin4D 2026.07.0 renames the project. The Python package, console +scripts, GitHub repository, and PyPI project all move to the new name; +there is no functional change. + 2026.05.07 Beta =============== -PhysioMotion4D 2026.05.07 is a beta release focused on public packaging, +PhysioTwin4D 2026.05.07 is a beta release focused on public packaging, documentation, tutorial workflows, and release automation. Highlights diff --git a/docs/cli_scripts/4dct_reconstruction.rst b/docs/cli_scripts/4dct_reconstruction.rst index b51606c..5daa30a 100644 --- a/docs/cli_scripts/4dct_reconstruction.rst +++ b/docs/cli_scripts/4dct_reconstruction.rst @@ -2,7 +2,7 @@ High-Resolution 4D CT Reconstruction ==================================== -The ``physiomotion4d-reconstruct-highres-4d-ct`` command reconstructs a +The ``physiotwin4d-reconstruct-highres-4d-ct`` command reconstructs a high-resolution 4D CT time series from ordered phase images and a high-resolution reference image. @@ -14,7 +14,7 @@ Input Requirements * A fixed high-resolution reference image. * Optional fixed and moving masks for registration focus. -DirLab-4DCT data cannot be downloaded automatically by PhysioMotion4D. Prepare +DirLab-4DCT data cannot be downloaded automatically by PhysioTwin4D. Prepare it manually before using the DirLab tutorial or examples. Basic Usage @@ -22,7 +22,7 @@ Basic Usage .. code-block:: bash - physiomotion4d-reconstruct-highres-4d-ct \ + physiotwin4d-reconstruct-highres-4d-ct \ --time-series-images frame_*.mha \ --fixed-image highres_reference.mha \ --output-dir ./results @@ -32,7 +32,7 @@ Choosing a Reference Frame .. code-block:: bash - physiomotion4d-reconstruct-highres-4d-ct \ + physiotwin4d-reconstruct-highres-4d-ct \ --time-series-images frame_000.mha frame_001.mha frame_002.mha \ --fixed-image highres_reference.mha \ --reference-frame 0 \ @@ -43,7 +43,7 @@ Registration Options .. code-block:: bash - physiomotion4d-reconstruct-highres-4d-ct \ + physiotwin4d-reconstruct-highres-4d-ct \ --time-series-images frame_*.mha \ --fixed-image highres_reference.mha \ --registration-method Greedy_ICON \ @@ -61,7 +61,7 @@ The command writes reconstructed images to ``--output-dir`` using Python API ========== -Use :class:`physiomotion4d.WorkflowReconstructHighres4DCT` for programmatic +Use :class:`physiotwin4d.WorkflowReconstructHighres4DCT` for programmatic access. Related Pages diff --git a/docs/cli_scripts/best_practices.rst b/docs/cli_scripts/best_practices.rst index 1a7679a..7a683a5 100644 --- a/docs/cli_scripts/best_practices.rst +++ b/docs/cli_scripts/best_practices.rst @@ -2,7 +2,7 @@ Best Practices ==================================== -This guide provides recommendations for optimal use of PhysioMotion4D CLI scripts, focusing on data preparation, processing strategies, and troubleshooting approaches. +This guide provides recommendations for optimal use of PhysioTwin4D CLI scripts, focusing on data preparation, processing strategies, and troubleshooting approaches. Data Preparation ================ @@ -103,7 +103,7 @@ Workflow Optimization patient_id=$(basename "$patient_dir") echo "Processing $patient_id" - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ ${patient_dir}/*.nrrd \ --contrast \ --output-dir processing/${patient_id} \ @@ -143,7 +143,7 @@ After processing, verify: Automated Quality Metrics -------------------------- -PhysioMotion4D logs quality metrics during processing: +PhysioTwin4D logs quality metrics during processing: * **Segmentation confidence**: Check for low-confidence regions * **Registration error**: Monitor convergence @@ -227,7 +227,7 @@ Ensuring Reproducible Results ------------------------------ **Version Control** - * Record PhysioMotion4D version: ``pip show physiomotion4d`` + * Record PhysioTwin4D version: ``pip show physiotwin4d`` * Document dependency versions * Use virtual environments @@ -242,7 +242,7 @@ Ensuring Reproducible Results # processing_metadata.yaml patient_id: patient_001 - physiomotion4d_version: {{ pm4d_project_version }} + physiotwin4d_version: {{ pt4d_project_version }} script: heart-gated-ct date: 2026-01-08 @@ -279,7 +279,7 @@ For non-gated multi-phase acquisitions (e.g., arterial/venous/delayed): .. code-block:: bash - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ arterial.nrrd \ venous.nrrd \ delayed.nrrd \ @@ -293,7 +293,7 @@ Process multiple patients in parallel: .. code-block:: bash # Using GNU parallel - parallel -j 4 'physiomotion4d-convert-image-to-usd {}/*.nrrd \ + parallel -j 4 'physiotwin4d-convert-image-to-usd {}/*.nrrd \ --output-dir results/{/} \ --project-name {/}' ::: raw_data/patient_* @@ -310,7 +310,7 @@ If you encounter issues not covered here: 4. Check GitHub issues for similar problems 5. Open new GitHub issue with: - * PhysioMotion4D version + * PhysioTwin4D version * Complete command used * Error messages * System information diff --git a/docs/cli_scripts/brain_vessel_modeling.rst b/docs/cli_scripts/brain_vessel_modeling.rst index 6f6217d..a986949 100644 --- a/docs/cli_scripts/brain_vessel_modeling.rst +++ b/docs/cli_scripts/brain_vessel_modeling.rst @@ -4,7 +4,7 @@ Brain Vessel Modeling Status ============================ -PhysioMotion4D does not currently install a brain-vessel modeling CLI command. +PhysioTwin4D does not currently install a brain-vessel modeling CLI command. Earlier research experiments helped shape the toolkit, but they are not supported usage examples for users or developers. diff --git a/docs/cli_scripts/byod_tutorials.rst b/docs/cli_scripts/byod_tutorials.rst index 1823b0c..60df479 100644 --- a/docs/cli_scripts/byod_tutorials.rst +++ b/docs/cli_scripts/byod_tutorials.rst @@ -3,7 +3,7 @@ Bring Your Own Data - DICOM, Images & VTK to USD ================================================ -PhysioMotion4D lets you convert your own medical imaging data into OpenUSD for +PhysioTwin4D lets you convert your own medical imaging data into OpenUSD for interactive visualization in NVIDIA Omniverse. Image inputs may be a directory of 3D or 4D DICOM data, a single 3D or 4D file in a common medical image format such as MHA, NRRD, or NIfTI, or a list of 3D image files representing a time @@ -11,7 +11,7 @@ series. VTK inputs may be one mesh file or a mesh sequence. .. note:: - PhysioMotion4D is a research tool and has **not** been validated for + PhysioTwin4D is a research tool and has **not** been validated for clinical use. Outputs must not be used for diagnostic or therapeutic decisions without independent validation. @@ -24,18 +24,18 @@ or the CPU-only variant: .. code-block:: bash # Recommended - CUDA-enabled - pip install physiomotion4d[cuda13] + pip install physiotwin4d[cuda13] # CPU-only - pip install physiomotion4d + pip install physiotwin4d Verify that all three relevant CLI entry-points are available after installation: .. code-block:: bash - physiomotion4d-download-data --help - physiomotion4d-convert-image-to-usd --help - physiomotion4d-convert-vtk-to-usd --help + physiotwin4d-download-data --help + physiotwin4d-convert-image-to-usd --help + physiotwin4d-convert-vtk-to-usd --help See :doc:`/installation` for prerequisites, CUDA version requirements, and source-based installation. @@ -47,14 +47,14 @@ Use the installed download CLI to fetch the public Slicer-Heart 4D CT sample: .. code-block:: bash - physiomotion4d-download-data + physiotwin4d-download-data This stores ``TruncalValve_4DCT.seq.nrrd`` under ``data/Slicer-Heart-CT``. To choose a different location: .. code-block:: bash - physiomotion4d-download-data Slicer-Heart-CT \ + physiotwin4d-download-data Slicer-Heart-CT \ --directory path/to/Slicer-Heart-CT DICOM and Medical Images to USD @@ -74,12 +74,12 @@ scene. .. code-block:: bash - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ patient_dicom_dir \ --output-dir ./results \ --project-name patient_heart - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ patient_ct.mha \ --output-dir ./results \ --project-name patient_heart @@ -88,11 +88,11 @@ scene. .. code-block:: python - import physiomotion4d as pm4d + import physiotwin4d as pt4d - workflow = pm4d.WorkflowConvertImageToUSD( + workflow = pt4d.WorkflowConvertImageToUSD( input_filenames=["patient_dicom_dir"], - segmentation_method=pm4d.SegmentChestTotalSegmentator(), + segmentation_method=pt4d.SegmentChestTotalSegmentator(), output_directory="./results", project_name="patient_heart", ) @@ -115,17 +115,17 @@ selects its default reference frame internally. .. code-block:: bash - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ gated_ct_dicom_dir \ --output-dir ./results \ --project-name heart_animated - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ gated_ct_4d.nrrd \ --output-dir ./results \ --project-name heart_animated - physiomotion4d-convert-image-to-usd \ + physiotwin4d-convert-image-to-usd \ phase_000.mha phase_001.mha phase_002.mha \ --output-dir ./results \ --fps 30 \ @@ -135,11 +135,11 @@ selects its default reference frame internally. .. code-block:: python - import physiomotion4d as pm4d + import physiotwin4d as pt4d - workflow = pm4d.WorkflowConvertImageToUSD( + workflow = pt4d.WorkflowConvertImageToUSD( input_filenames=["phase_000.mha", "phase_001.mha", "phase_002.mha"], - segmentation_method=pm4d.SegmentChestTotalSegmentator(), + segmentation_method=pt4d.SegmentChestTotalSegmentator(), output_directory="./results", project_name="heart_animated", times_per_second=30.0, @@ -163,13 +163,13 @@ Pass a single ``.vtp`` file. Use ``--appearance`` to control material style and .. code-block:: bash # Default - split by connected component, anatomy material - physiomotion4d-convert-vtk-to-usd heart.vtp \ + physiotwin4d-convert-vtk-to-usd heart.vtp \ --output heart.usd \ --appearance anatomy \ --anatomy-type heart # Solid color, no splitting - physiomotion4d-convert-vtk-to-usd mesh.vtp \ + physiotwin4d-convert-vtk-to-usd mesh.vtp \ --output mesh_red.usd \ --appearance solid \ --color 0.8 0.1 0.1 \ @@ -179,9 +179,9 @@ Pass a single ``.vtp`` file. Use ``--appearance`` to control material style and .. code-block:: python - import physiomotion4d as pm4d + import physiotwin4d as pt4d - workflow = pm4d.WorkflowConvertVTKToUSD( + workflow = pt4d.WorkflowConvertVTKToUSD( vtk_files=["heart.vtp"], output_usd="heart.usd", appearance="anatomy", @@ -203,12 +203,12 @@ rate. For scalar colormaps, combine ``--primvar``, ``--cmap``, and .. code-block:: bash # Animated mesh sequence - physiomotion4d-convert-vtk-to-usd heart.t0.vtp heart.t1.vtp heart.t2.vtp \ + physiotwin4d-convert-vtk-to-usd heart.t0.vtp heart.t1.vtp heart.t2.vtp \ --output heart_animation.usd \ --fps 30 # Animated with scalar colormap (e.g. wall stress) - physiomotion4d-convert-vtk-to-usd stress.t0.vtk stress.t1.vtk stress.t2.vtk \ + physiotwin4d-convert-vtk-to-usd stress.t0.vtk stress.t1.vtk stress.t2.vtk \ --output stress_animation.usd \ --fps 30 \ --appearance colormap \ @@ -220,9 +220,9 @@ rate. For scalar colormaps, combine ``--primvar``, ``--cmap``, and .. code-block:: python - import physiomotion4d as pm4d + import physiotwin4d as pt4d - workflow = pm4d.WorkflowConvertVTKToUSD( + workflow = pt4d.WorkflowConvertVTKToUSD( vtk_files=["stress.t0.vtk", "stress.t1.vtk", "stress.t2.vtk"], output_usd="stress_animation.usd", times_per_second=30, @@ -236,17 +236,17 @@ rate. For scalar colormaps, combine ``--primvar``, ``--cmap``, and **Lower-level in-memory conversion with ConvertVTKToUSD:** For programmatic pipelines where meshes are already in memory, use the -lower-level :class:`physiomotion4d.ConvertVTKToUSD` class directly: +lower-level :class:`physiotwin4d.ConvertVTKToUSD` class directly: .. code-block:: python import pyvista as pv - import physiomotion4d as pm4d + import physiotwin4d as pt4d # Load or construct meshes in memory meshes = [pv.read(f"frame_{i:04d}.vtp") for i in range(10)] - converter = pm4d.ConvertVTKToUSD( + converter = pt4d.ConvertVTKToUSD( data_basename="HeartAnimation", input_polydata=meshes, times_per_second=30, @@ -260,9 +260,9 @@ Viewing Results .. code-block:: python - import physiomotion4d as pm4d + import physiotwin4d as pt4d - mesh = pm4d.USDTools().load_usd_as_vtk("output.usd") + mesh = pt4d.USDTools().load_usd_as_vtk("output.usd") print(mesh.n_points, mesh.n_cells) PyVista reads the VTK input files used above, but local validation with @@ -291,7 +291,7 @@ See Also 4D Isaac for Healthcare Assets ------------------------------ -PhysioMotion4D has been used to generate a number of 4D anatomic models for +PhysioTwin4D has been used to generate a number of 4D anatomic models for Isaac for Healthcare. These datasets are intended to support visualization and workflow development with time-varying anatomy in OpenUSD. diff --git a/docs/cli_scripts/create_statistical_model.rst b/docs/cli_scripts/create_statistical_model.rst index 12e5e5b..2509edb 100644 --- a/docs/cli_scripts/create_statistical_model.rst +++ b/docs/cli_scripts/create_statistical_model.rst @@ -5,7 +5,7 @@ Create Statistical Model Overview ======== -The ``physiomotion4d-create-statistical-model`` command-line tool builds a PCA +The ``physiotwin4d-create-statistical-model`` command-line tool builds a PCA (Principal Component Analysis) statistical shape model from a sample of meshes aligned to a reference mesh. This mirrors the pipeline in the Heart-Create_Statistical_Model experiment scripts. @@ -23,17 +23,17 @@ Outputs written to the output directory: * ``pca_mean_surface.vtp`` — Mean shape as a surface (PolyData) * ``pca_mean.vtu`` — Reference volume mesh in mean space (only if reference is volumetric) * ``pca_model.json`` — PCA model (eigenvalues, components) for use with - :class:`physiomotion4d.WorkflowFitStatisticalModelToPatient` or - :class:`physiomotion4d.RegisterModelsPCA` + :class:`physiotwin4d.WorkflowFitStatisticalModelToPatient` or + :class:`physiotwin4d.RegisterModelsPCA` Installation ============ -The script is installed with PhysioMotion4D: +The script is installed with PhysioTwin4D: .. code-block:: bash - pip install physiomotion4d + pip install physiotwin4d Quick Start =========== @@ -45,7 +45,7 @@ Create a PCA model from a directory of sample meshes and a reference mesh: .. code-block:: bash - physiomotion4d-create-statistical-model \ + physiotwin4d-create-statistical-model \ --sample-meshes-dir ./input_meshes \ --reference-mesh average_mesh.vtk \ --output-dir ./pca_output @@ -57,7 +57,7 @@ Provide sample mesh paths explicitly instead of a directory: .. code-block:: bash - physiomotion4d-create-statistical-model \ + physiotwin4d-create-statistical-model \ --sample-meshes 01.vtk 02.vtk 03.vtu 04.vtp \ --reference-mesh average_mesh.vtk \ --output-dir ./pca_output @@ -67,7 +67,7 @@ With Custom Parameters .. code-block:: bash - physiomotion4d-create-statistical-model \ + physiotwin4d-create-statistical-model \ --sample-meshes-dir ./meshes \ --reference-mesh average_mesh.vtk \ --output-dir ./pca_output \ @@ -97,6 +97,6 @@ Optional Arguments ``--pca-components N`` Number of PCA components to retain (default: 15). -See :class:`physiomotion4d.WorkflowCreateStatisticalModel` for the full API and +See :class:`physiotwin4d.WorkflowCreateStatisticalModel` for the full API and additional parameters (e.g. ``reference_spatial_resolution``, ``reference_buffer_factor``) that can be exposed in future CLI versions. diff --git a/docs/cli_scripts/download_data.rst b/docs/cli_scripts/download_data.rst index dc7f800..862fad9 100644 --- a/docs/cli_scripts/download_data.rst +++ b/docs/cli_scripts/download_data.rst @@ -2,8 +2,8 @@ Download Example Data ===================== -The ``physiomotion4d-download-data`` command downloads example datasets used by -PhysioMotion4D tutorials and demos. +The ``physiotwin4d-download-data`` command downloads example datasets used by +PhysioTwin4D tutorials and demos. Supported Datasets ================== @@ -16,7 +16,7 @@ Supported Datasets - Description * - ``Slicer-Heart-CT`` - Public 4D cardiac CT sample from SlicerHeart. This is currently the - only dataset downloaded automatically by PhysioMotion4D. + only dataset downloaded automatically by PhysioTwin4D. Basic Usage =========== @@ -25,13 +25,13 @@ Download the default dataset into the default location: .. code-block:: bash - physiomotion4d-download-data + physiotwin4d-download-data This is equivalent to: .. code-block:: bash - physiomotion4d-download-data Slicer-Heart-CT \ + physiotwin4d-download-data Slicer-Heart-CT \ --directory data/Slicer-Heart-CT Options @@ -39,7 +39,7 @@ Options .. code-block:: bash - physiomotion4d-download-data [Slicer-Heart-CT] [--directory DIRECTORY] + physiotwin4d-download-data [Slicer-Heart-CT] [--directory DIRECTORY] ``data_name`` Dataset to download. The only accepted value is ``Slicer-Heart-CT``. @@ -58,7 +58,7 @@ For ``Slicer-Heart-CT``, the command downloads or reuses: data/Slicer-Heart-CT/TruncalValve_4DCT.seq.nrrd The command uses -:meth:`physiomotion4d.data_download_tools.DataDownloadTools.DownloadSlicerHeartCTData`, +:meth:`physiotwin4d.data_download_tools.DataDownloadTools.DownloadSlicerHeartCTData`, so repeated runs reuse the existing non-empty file. See Also diff --git a/docs/cli_scripts/fit_statistical_model_to_patient.rst b/docs/cli_scripts/fit_statistical_model_to_patient.rst index f763f5a..11ff2cf 100644 --- a/docs/cli_scripts/fit_statistical_model_to_patient.rst +++ b/docs/cli_scripts/fit_statistical_model_to_patient.rst @@ -5,7 +5,7 @@ Heart Model to Patient Registration Overview ======== -The ``physiomotion4d-fit-statistical-model-to-patient`` command-line tool registers generic anatomical heart models to patient-specific imaging data and surface models. This workflow enables: +The ``physiotwin4d-fit-statistical-model-to-patient`` command-line tool registers generic anatomical heart models to patient-specific imaging data and surface models. This workflow enables: * Patient-specific anatomical modeling from generic templates * Multi-stage registration combining ICP, PCA, and deformable methods @@ -22,11 +22,11 @@ The registration pipeline consists of four stages: Installation ============ -The script is included with PhysioMotion4D installation: +The script is included with PhysioTwin4D installation: .. code-block:: bash - pip install physiomotion4d + pip install physiotwin4d Quick Start =========== @@ -38,7 +38,7 @@ Register a generic heart model to patient data: .. code-block:: bash - physiomotion4d-fit-statistical-model-to-patient \ + physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp myo.vtp \ @@ -52,7 +52,7 @@ Include statistical shape model fitting: .. code-block:: bash - physiomotion4d-fit-statistical-model-to-patient \ + physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp myo.vtp \ @@ -86,7 +86,7 @@ Optional inputs: Path to template labelmap image (.nii.gz, .nrrd, .mha). Required only when ``--labelmap-to-image`` is set. -See :class:`physiomotion4d.WorkflowFitStatisticalModelToPatient` for API documentation. +See :class:`physiotwin4d.WorkflowFitStatisticalModelToPatient` for API documentation. Template Labelmap Configuration -------------------------------- @@ -144,7 +144,7 @@ Example 1: Basic Registration .. code-block:: bash - physiomotion4d-fit-statistical-model-to-patient \ + physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp myo.vtp \ @@ -156,7 +156,7 @@ Example 2: PCA-Based Registration .. code-block:: bash - physiomotion4d-fit-statistical-model-to-patient \ + physiotwin4d-fit-statistical-model-to-patient \ --template-model heart_model.vtu \ --template-labelmap heart_labelmap.nii.gz \ --patient-models lv.vtp rv.vtp \ diff --git a/docs/cli_scripts/heart_gated_ct.rst b/docs/cli_scripts/heart_gated_ct.rst index 18a1089..8d81229 100644 --- a/docs/cli_scripts/heart_gated_ct.rst +++ b/docs/cli_scripts/heart_gated_ct.rst @@ -7,7 +7,7 @@ Process cardiac gated CT images into dynamic, animated heart models for visualiz Overview ======== -The ``physiomotion4d-convert-image-to-usd`` script processes 4D cardiac CT scans through a complete pipeline that includes: +The ``physiotwin4d-convert-image-to-usd`` script processes 4D cardiac CT scans through a complete pipeline that includes: * AI-based anatomical segmentation * Deformable image registration across cardiac phases @@ -56,21 +56,21 @@ Single 4D File .. code-block:: bash - physiomotion4d-convert-image-to-usd cardiac_4d.nrrd --contrast + physiotwin4d-convert-image-to-usd cardiac_4d.nrrd --contrast Multiple 3D Files ----------------- .. code-block:: bash - physiomotion4d-convert-image-to-usd phase_*.nrrd --contrast --project-name patient_001 + physiotwin4d-convert-image-to-usd phase_*.nrrd --contrast --project-name patient_001 With Output Directory --------------------- .. code-block:: bash - physiomotion4d-convert-image-to-usd cardiac.nrrd \ + physiotwin4d-convert-image-to-usd cardiac.nrrd \ --contrast \ --output-dir ./results/patient_001 \ --project-name patient_001 @@ -186,7 +186,7 @@ Contrast-Enhanced Cardiac CTA .. code-block:: bash - physiomotion4d-convert-image-to-usd cardiac_cta.nrrd \ + physiotwin4d-convert-image-to-usd cardiac_cta.nrrd \ --contrast \ --output-dir ./output/patient_123 \ --project-name PatientXYZ_CTA @@ -196,7 +196,7 @@ Non-Contrast Study with Custom Reference .. code-block:: bash - physiomotion4d-convert-image-to-usd phase_*.nrrd \ + physiotwin4d-convert-image-to-usd phase_*.nrrd \ --reference-image phase_05.mha \ --output-dir ./results \ --project-name noncontrast_cardiac @@ -209,7 +209,7 @@ Research Dataset Processing # Batch process multiple cases for case_dir in /data/cardiac_studies/case_*/; do case_name=$(basename "$case_dir") - physiomotion4d-convert-image-to-usd ${case_dir}/*.nrrd \ + physiotwin4d-convert-image-to-usd ${case_dir}/*.nrrd \ --contrast \ --output-dir ./results/${case_name} \ --project-name ${case_name} @@ -220,7 +220,7 @@ With Greedy Registration .. code-block:: bash - physiomotion4d-convert-image-to-usd cardiac.nrrd \ + physiotwin4d-convert-image-to-usd cardiac.nrrd \ --contrast \ --registration-method Greedy \ --registration-iterations 50 @@ -340,4 +340,4 @@ Next Steps * See :doc:`best_practices` for optimization strategies * Review :doc:`../troubleshooting` for common issues -* For Python API access, see :class:`physiomotion4d.WorkflowConvertImageToUSD` in :doc:`../developer/workflows` +* For Python API access, see :class:`physiotwin4d.WorkflowConvertImageToUSD` in :doc:`../developer/workflows` diff --git a/docs/cli_scripts/lung_gated_ct.rst b/docs/cli_scripts/lung_gated_ct.rst index 68b1fd7..f51394c 100644 --- a/docs/cli_scripts/lung_gated_ct.rst +++ b/docs/cli_scripts/lung_gated_ct.rst @@ -4,7 +4,7 @@ Lung-Gated CT Status ===================== -PhysioMotion4D does not currently install a dedicated lung-gated CT CLI command. +PhysioTwin4D does not currently install a dedicated lung-gated CT CLI command. Respiratory 4D CT work is represented by the high-resolution reconstruction workflow and Tutorial 6, which requires manually prepared DirLab-4DCT data. @@ -12,4 +12,4 @@ Use these supported resources instead: * :doc:`4dct_reconstruction` * :doc:`../tutorials` -* :class:`physiomotion4d.WorkflowReconstructHighres4DCT` +* :class:`physiotwin4d.WorkflowReconstructHighres4DCT` diff --git a/docs/cli_scripts/overview.rst b/docs/cli_scripts/overview.rst index 75d0a8d..b95faf8 100644 --- a/docs/cli_scripts/overview.rst +++ b/docs/cli_scripts/overview.rst @@ -2,15 +2,15 @@ CLI & Scripts Overview ==================================== -This section provides comprehensive guides for using PhysioMotion4D's command-line tools to process medical imaging data. These tools are designed for medical imaging experts and physiological simulation researchers who need efficient, reproducible pipelines for converting 4D medical images into dynamic anatomical models for NVIDIA Omniverse. +This section provides comprehensive guides for using PhysioTwin4D's command-line tools to process medical imaging data. These tools are designed for medical imaging experts and physiological simulation researchers who need efficient, reproducible pipelines for converting 4D medical images into dynamic anatomical models for NVIDIA Omniverse. How to Use These Resources ========================== -PhysioMotion4D exposes the same toolkit through three user-facing layers: +PhysioTwin4D exposes the same toolkit through three user-facing layers: * **Workflows** are Python classes that orchestrate complete processing - pipelines. Use them when integrating PhysioMotion4D into Python applications + pipelines. Use them when integrating PhysioTwin4D into Python applications or when you need programmatic control over inputs, outputs, and parameters. * **CLIs** are installed command-line wrappers around workflow classes. Use them for repeatable processing runs, batch jobs, and environment validation without @@ -35,7 +35,7 @@ These CLI tools are intended for users with: * Modest Python experience for running scripts * Familiarity with command-line interfaces -If you are a Python developer looking to extend or integrate PhysioMotion4D into your applications, please refer to the :doc:`../developer/architecture` section. +If you are a Python developer looking to extend or integrate PhysioTwin4D into your applications, please refer to the :doc:`../developer/architecture` section. Available Scripts ================= @@ -50,12 +50,12 @@ Current Scripts * - Script - Description * - :doc:`download_data` - - Download supported PhysioMotion4D example datasets + - Download supported PhysioTwin4D example datasets * - :doc:`heart_gated_ct` - Process cardiac gated CT to animated heart models with physiological motion - * - ``physiomotion4d-convert-image-to-vtk`` + * - ``physiotwin4d-convert-image-to-vtk`` - Segment one 3D image and export anatomy-group VTK surfaces and meshes - * - ``physiomotion4d-convert-image-4d-to-3d`` + * - ``physiotwin4d-convert-image-4d-to-3d`` - Split a 4D medical image into a 3D time series using ITK readers * - :doc:`create_statistical_model` - Build a PCA statistical shape model from sample meshes aligned to a reference @@ -65,29 +65,29 @@ Current Scripts - Reconstruct high-resolution 4D CT from time-series images and a reference * - :doc:`vtk_to_usd` - Convert VTK anatomical models to USD format with material painting - * - ``physiomotion4d-visualize-pca-modes`` + * - ``physiotwin4d-visualize-pca-modes`` - Render PCA model mode visualizations Installation ============ -All scripts are installed with the PhysioMotion4D package: +All scripts are installed with the PhysioTwin4D package: .. code-block:: bash - pip install physiomotion4d + pip install physiotwin4d -After installation, scripts are available as command-line tools with the prefix ``physiomotion4d-``: +After installation, scripts are available as command-line tools with the prefix ``physiotwin4d-``: .. code-block:: bash - physiomotion4d-convert-image-to-usd --help - physiomotion4d-download-data --help + physiotwin4d-convert-image-to-usd --help + physiotwin4d-download-data --help General Workflow ================ -All PhysioMotion4D scripts follow a similar pattern: +All PhysioTwin4D scripts follow a similar pattern: 1. **Input Data**: Provide medical image files (NRRD, NII, MHA formats) 2. **Configuration**: Set processing parameters via command-line flags @@ -99,7 +99,7 @@ Typical Command Structure .. code-block:: bash - physiomotion4d- --help + physiotwin4d- --help Use each command's ``--help`` output as the source of truth for required arguments and script-specific options. @@ -123,7 +123,7 @@ Each script provides detailed help: .. code-block:: bash - physiomotion4d- --help + physiotwin4d- --help For troubleshooting and common issues, see :doc:`../troubleshooting`. diff --git a/docs/cli_scripts/vtk_to_usd.rst b/docs/cli_scripts/vtk_to_usd.rst index fa92b63..58f8164 100644 --- a/docs/cli_scripts/vtk_to_usd.rst +++ b/docs/cli_scripts/vtk_to_usd.rst @@ -2,7 +2,7 @@ VTK to USD Conversion ===================== -The ``physiomotion4d-convert-vtk-to-usd`` command converts VTK, VTP, or VTU +The ``physiotwin4d-convert-vtk-to-usd`` command converts VTK, VTP, or VTU mesh files to USD for Omniverse visualization. Multiple input files are treated as a time series. @@ -11,7 +11,7 @@ Basic Usage .. code-block:: bash - physiomotion4d-convert-vtk-to-usd heart.vtp \ + physiotwin4d-convert-vtk-to-usd heart.vtp \ --output heart.usd Time Series @@ -19,7 +19,7 @@ Time Series .. code-block:: bash - physiomotion4d-convert-vtk-to-usd heart_*.vtp \ + physiotwin4d-convert-vtk-to-usd heart_*.vtp \ --output heart_animation.usd \ --fps 30 @@ -30,7 +30,7 @@ Solid color: .. code-block:: bash - physiomotion4d-convert-vtk-to-usd heart.vtp \ + physiotwin4d-convert-vtk-to-usd heart.vtp \ --output heart_red.usd \ --appearance solid \ --color 1 0 0 @@ -39,7 +39,7 @@ Anatomy material: .. code-block:: bash - physiomotion4d-convert-vtk-to-usd heart.vtp \ + physiotwin4d-convert-vtk-to-usd heart.vtp \ --output heart_material.usd \ --appearance anatomy \ --anatomy-type heart @@ -48,7 +48,7 @@ Colormap from a VTK point data array: .. code-block:: bash - physiomotion4d-convert-vtk-to-usd frame_*.vtk \ + physiotwin4d-convert-vtk-to-usd frame_*.vtk \ --output stress.usd \ --appearance colormap \ --primvar vtk_point_stress_c0 \ @@ -63,15 +63,15 @@ one mesh, or ``--by-cell-type`` to split by cell type. .. code-block:: bash - physiomotion4d-convert-vtk-to-usd mesh.vtu \ + physiotwin4d-convert-vtk-to-usd mesh.vtu \ --output mesh.usd \ --by-cell-type Python API ========== -Use :class:`physiomotion4d.WorkflowConvertVTKToUSD` for the workflow API and -:class:`physiomotion4d.ConvertVTKToUSD` for direct in-memory conversion. +Use :class:`physiotwin4d.WorkflowConvertVTKToUSD` for the workflow API and +:class:`physiotwin4d.ConvertVTKToUSD` for direct in-memory conversion. Related Pages ============= diff --git a/docs/conf.py b/docs/conf.py index 91f9326..6e0a9d4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,7 +30,7 @@ def __getattr__(cls, name): sys.modules["icon_registration.network_wrappers"] = Mock() # -- Project information ----------------------------------------------------- -project = "PhysioMotion4D" +project = "PhysioTwin4D" copyright = f"{datetime.now().year}, Stephen R. Aylward, NVIDIA Corporation" author = "Stephen R. Aylward" _repo_root = Path(__file__).resolve().parents[1] @@ -115,7 +115,7 @@ def __getattr__(cls, name): html_context = { "display_github": True, "github_user": "Project-MONAI", - "github_repo": "physiomotion4d", + "github_repo": "physiotwin4d", "github_version": "main", "conf_py_path": "/docs/", } @@ -232,7 +232,7 @@ def autodoc_skip_member(app, what, name, obj, skip, options): def _replace_project_version_token(_app, _docname, source): - source[0] = source[0].replace("{{ pm4d_project_version }}", release) + source[0] = source[0].replace("{{ pt4d_project_version }}", release) def setup(app): diff --git a/docs/contributing.rst b/docs/contributing.rst index d6b5d96..43a1e54 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,7 +2,7 @@ Contributing ============ -Thank you for your interest in contributing to PhysioMotion4D! This guide will help you get started. +Thank you for your interest in contributing to PhysioTwin4D! This guide will help you get started. Ways to Contribute =================== @@ -21,8 +21,8 @@ Getting Started .. code-block:: bash - git clone https://github.com/YOUR_USERNAME/PhysioMotion4D.git - cd PhysioMotion4D + git clone https://github.com/YOUR_USERNAME/PhysioTwin4D.git + cd PhysioTwin4D 3. **Create a virtual environment**: @@ -136,7 +136,7 @@ After cloning the repository: Code Style ========== -PhysioMotion4D follows strict code quality standards using modern, fast tooling. +PhysioTwin4D follows strict code quality standards using modern, fast tooling. Formatting and Linting with Ruff --------------------------------- @@ -240,7 +240,7 @@ Add tests in the ``tests/`` directory: # tests/test_my_feature.py import pytest - from physiomotion4d import MyNewFeature + from physiotwin4d import MyNewFeature def test_my_feature(): feature = MyNewFeature() @@ -259,7 +259,7 @@ Run Tests pytest tests/test_my_feature.py -v # Run with coverage - pytest tests/ --cov=src/physiomotion4d --cov-report=html + pytest tests/ --cov=src/physiotwin4d --cov-report=html # Default invocation auto-skips slow/GPU/Simpleware/experiment/tutorial pytest tests/ @@ -306,7 +306,7 @@ Contributing Scripts vs Experiments When contributing new workflows or examples: -**Production Code (src/physiomotion4d/cli/):** +**Production Code (src/physiotwin4d/cli/):** * **DO contribute here** for production-ready CLI implementations * Must include proper error handling and validation @@ -320,7 +320,7 @@ When contributing new workflows or examples: * Can have hardcoded paths and minimal error handling * Should document what was learned and how it informed production code * Helps others understand adaptation possibilities for new domains -* Should reference corresponding production implementation in CLI commands or ``src/physiomotion4d/cli/`` +* Should reference corresponding production implementation in CLI commands or ``src/physiotwin4d/cli/`` Docstring Format ---------------- @@ -382,7 +382,7 @@ Bug Reports When reporting bugs, include: * **Python version** -* **PhysioMotion4D version** +* **PhysioTwin4D version** * **Operating system** * **GPU/CUDA version** (if applicable) * **Minimal code** to reproduce @@ -405,13 +405,13 @@ Release Process Versioning ---------- -PhysioMotion4D uses calendar versioning: ``YYYY.0M.PATCH`` +PhysioTwin4D uses calendar versioning: ``YYYY.0M.PATCH`` * **YYYY**: Year * **0M**: Zero-padded month * **PATCH**: Patch number within month -Example: ``{{ pm4d_project_version }}`` +Example: ``{{ pt4d_project_version }}`` Making a Release ---------------- @@ -458,11 +458,11 @@ Apache 2.0 License. Acknowledgments =============== -Thank you to all contributors who help make PhysioMotion4D better! +Thank you to all contributors who help make PhysioTwin4D better! See Also ======== * :doc:`architecture` - System architecture * :doc:`testing` - Testing guide -* `GitHub Repository `_ +* `GitHub Repository `_ diff --git a/docs/developer/architecture.rst b/docs/developer/architecture.rst index a8b2f55..0584f97 100644 --- a/docs/developer/architecture.rst +++ b/docs/developer/architecture.rst @@ -2,9 +2,9 @@ Architecture Overview ===================== -PhysioMotion4D is an early-beta scientific Python package built from workflow +PhysioTwin4D is an early-beta scientific Python package built from workflow classes plus reusable segmentation, registration, geometry, image, and USD -components. Runtime classes inherit from :class:`PhysioMotion4DBase` for +components. Runtime classes inherit from :class:`PhysioTwin4DBase` for logging and consistent configuration. Architecture Diagram diff --git a/docs/developer/core.rst b/docs/developer/core.rst index 6d461fb..30f8b53 100644 --- a/docs/developer/core.rst +++ b/docs/developer/core.rst @@ -2,21 +2,21 @@ Core Developer Guide ====================== -This page summarizes the core conventions for extending PhysioMotion4D. +This page summarizes the core conventions for extending PhysioTwin4D. Base Class ========== -Runtime classes inherit from :class:`physiomotion4d.PhysioMotion4DBase` and use +Runtime classes inherit from :class:`physiotwin4d.PhysioTwin4DBase` and use the shared logging methods. .. code-block:: python import logging - from physiomotion4d import PhysioMotion4DBase + from physiotwin4d import PhysioTwin4DBase - class MyWorkflow(PhysioMotion4DBase): + class MyWorkflow(PhysioTwin4DBase): def __init__(self, input_file: str) -> None: super().__init__(class_name="MyWorkflow", log_level=logging.INFO) self.input_file = input_file diff --git a/docs/developer/extending.rst b/docs/developer/extending.rst index 82ef11f..511c152 100644 --- a/docs/developer/extending.rst +++ b/docs/developer/extending.rst @@ -1,8 +1,8 @@ ======================== -Extending PhysioMotion4D +Extending PhysioTwin4D ======================== -PhysioMotion4D is an early-alpha toolkit. Prefer small, explicit extensions +PhysioTwin4D is an early-alpha toolkit. Prefer small, explicit extensions that match the current class boundaries over large compatibility layers. Where to Start @@ -22,9 +22,9 @@ Runtime Class Pattern import logging - from physiomotion4d import PhysioMotion4DBase + from physiotwin4d import PhysioTwin4DBase - class MyWorkflow(PhysioMotion4DBase): + class MyWorkflow(PhysioTwin4DBase): def __init__(self, input_file: str, log_level: int | str = logging.INFO): super().__init__(class_name="MyWorkflow", log_level=log_level) self.input_file = input_file diff --git a/docs/developer/registration_images.rst b/docs/developer/registration_images.rst index 8be4545..dd649dd 100644 --- a/docs/developer/registration_images.rst +++ b/docs/developer/registration_images.rst @@ -2,7 +2,7 @@ Image Registration Developer Guide ================================== -PhysioMotion4D image registration classes register a moving ITK image to a +PhysioTwin4D image registration classes register a moving ITK image to a fixed ITK image. Basic Pattern @@ -12,7 +12,7 @@ Basic Pattern import itk - from physiomotion4d import RegisterImagesANTS + from physiotwin4d import RegisterImagesANTS fixed = itk.imread("fixed.mha") moving = itk.imread("moving.mha") @@ -38,7 +38,7 @@ Time Series import itk - from physiomotion4d import RegisterImagesGreedy, RegisterTimeSeriesImages + from physiotwin4d import RegisterImagesGreedy, RegisterTimeSeriesImages images = [itk.imread(f"phase_{idx:02d}.mha") for idx in range(10)] @@ -64,13 +64,13 @@ registration followed by ICON refinement: .. code-block:: python - from physiomotion4d import RegisterImagesChain, RegisterImagesGreedy, RegisterImagesICON + from physiotwin4d import RegisterImagesChain, RegisterImagesGreedy, RegisterImagesICON # Arbitrary N-stage chain registrar = RegisterImagesChain([RegisterImagesGreedy(), RegisterImagesICON()]) # Or, for the common Greedy-then-ICON case: - from physiomotion4d import RegisterImagesGreedyICON + from physiotwin4d import RegisterImagesGreedyICON registrar = RegisterImagesGreedyICON() registrar.greedy.set_number_of_iterations([30, 15, 7, 3]) diff --git a/docs/developer/registration_models.rst b/docs/developer/registration_models.rst index 466b904..f7cada6 100644 --- a/docs/developer/registration_models.rst +++ b/docs/developer/registration_models.rst @@ -4,7 +4,7 @@ Model Registration Developer Guide Model registration aligns template meshes to patient surfaces and masks. The supported high-level entry point is -:class:`physiomotion4d.WorkflowFitStatisticalModelToPatient`. +:class:`physiotwin4d.WorkflowFitStatisticalModelToPatient`. Recommended Entry Point ======================= @@ -14,7 +14,7 @@ Recommended Entry Point import itk import pyvista as pv - from physiomotion4d import WorkflowFitStatisticalModelToPatient + from physiotwin4d import WorkflowFitStatisticalModelToPatient workflow = WorkflowFitStatisticalModelToPatient( template_model=pv.read("template_heart.vtu"), @@ -29,10 +29,10 @@ Lower-Level Classes The workflow composes these lower-level registration classes: -* :class:`physiomotion4d.RegisterModelsICP` -* :class:`physiomotion4d.RegisterModelsICPITK` -* :class:`physiomotion4d.RegisterModelsDistanceMaps` -* :class:`physiomotion4d.RegisterModelsPCA` +* :class:`physiotwin4d.RegisterModelsICP` +* :class:`physiotwin4d.RegisterModelsICPITK` +* :class:`physiotwin4d.RegisterModelsDistanceMaps` +* :class:`physiotwin4d.RegisterModelsPCA` Use these directly only when developing or testing a specific registration stage. Their constructors and return dictionaries are documented in diff --git a/docs/developer/segmentation.rst b/docs/developer/segmentation.rst index 98073ec..9f05580 100644 --- a/docs/developer/segmentation.rst +++ b/docs/developer/segmentation.rst @@ -12,7 +12,7 @@ Current Segmentation Contract import itk - from physiomotion4d import SegmentChestTotalSegmentator + from physiotwin4d import SegmentChestTotalSegmentator image = itk.imread("chest_ct.nrrd") segmenter = SegmentChestTotalSegmentator() @@ -24,15 +24,15 @@ Current Segmentation Contract Segmentation outputs are dictionaries of ITK images. Access masks by key, not by positional unpacking. The exact key set depends on the segmenter's -:class:`physiomotion4d.AnatomyTaxonomy` — see :doc:`../api/segmentation/base` +:class:`physiotwin4d.AnatomyTaxonomy` — see :doc:`../api/segmentation/base` for the per-segmenter key sets and the general contract. Implemented Segmenters ====================== -* :class:`physiomotion4d.SegmentChestTotalSegmentator` -* :class:`physiomotion4d.SegmentHeartSimpleware` -* :class:`physiomotion4d.SegmentAnatomyBase` +* :class:`physiotwin4d.SegmentChestTotalSegmentator` +* :class:`physiotwin4d.SegmentHeartSimpleware` +* :class:`physiotwin4d.SegmentAnatomyBase` Adding a New Segmenter ====================== @@ -46,7 +46,7 @@ produces by populating ``self.taxonomy``. The base class owns the import logging - from physiomotion4d import SegmentAnatomyBase + from physiotwin4d import SegmentAnatomyBase class SegmentMySite(SegmentAnatomyBase): @@ -85,7 +85,7 @@ USD renderer doesn't fall back to the generic ``"other"`` material: .. code-block:: python - from physiomotion4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS + from physiotwin4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS DEFAULT_RENDER_PARAMS["brain"] = { "name": "Brain", diff --git a/docs/developer/transform_conventions.rst b/docs/developer/transform_conventions.rst index ee80cf0..4d6d3e1 100644 --- a/docs/developer/transform_conventions.rst +++ b/docs/developer/transform_conventions.rst @@ -2,7 +2,7 @@ Transform Direction Conventions =============================== -Registration in PhysioMotion4D produces a pair of transforms, and choosing the +Registration in PhysioTwin4D produces a pair of transforms, and choosing the wrong one of the pair is the single most common registration mistake. The rules are simple but easy to get backwards, because **warping an image and warping a point require opposite transforms**, and because **model (PCA) registration @@ -15,15 +15,15 @@ The two transform families =========================== Image registration - :class:`physiomotion4d.RegisterImagesANTS`, - :class:`physiomotion4d.RegisterImagesICON`, and - :class:`physiomotion4d.RegisterImagesGreedy` register a *moving* image to a + :class:`physiotwin4d.RegisterImagesANTS`, + :class:`physiotwin4d.RegisterImagesICON`, and + :class:`physiotwin4d.RegisterImagesGreedy` register a *moving* image to a *fixed* image and return a dict with ``forward_transform`` and - ``inverse_transform``. :class:`physiomotion4d.RegisterTimeSeriesImages` + ``inverse_transform``. :class:`physiotwin4d.RegisterTimeSeriesImages` returns the list-valued ``forward_transforms`` / ``inverse_transforms``. Model (PCA) registration - :class:`physiomotion4d.RegisterModelsPCA` deforms a *template* model toward + :class:`physiotwin4d.RegisterModelsPCA` deforms a *template* model toward a *target* (patient) and, via ``compute_pca_transforms()``, returns ``forward_point_transform`` and ``inverse_point_transform``. These are **point transforms**, oriented opposite to the image-registration transforms @@ -70,7 +70,7 @@ So for the **same** moving-to-fixed registration result: The first two rows are the everyday case (warping the registered moving data into the fixed/reference frame): the **image uses** ``forward_transform``, the **points use** ``inverse_transform``. The last two rows are the mirror image; -:meth:`physiomotion4d.RegisterTimeSeriesImages.reconstruct_time_series` is the +:meth:`physiotwin4d.RegisterTimeSeriesImages.reconstruct_time_series` is the canonical consumer of ``inverse_transform`` for image warping (it resamples the fixed image back onto each moving frame's grid). @@ -83,7 +83,7 @@ fixed image back onto each moving frame's grid). PCA point transforms ==================== -:class:`physiomotion4d.RegisterModelsPCA` builds ``forward_point_transform`` +:class:`physiotwin4d.RegisterModelsPCA` builds ``forward_point_transform`` directly from the template-to-target point displacement, so ``forward_point_transform.TransformPoint(template_point)`` returns the corresponding *target* point. As a **point** map it goes template (moving) to diff --git a/docs/developer/usd_generation.rst b/docs/developer/usd_generation.rst index 4d0375a..b92d453 100644 --- a/docs/developer/usd_generation.rst +++ b/docs/developer/usd_generation.rst @@ -2,19 +2,19 @@ USD Generation ======================== -PhysioMotion4D uses :class:`physiomotion4d.ConvertVTKToUSD` as the +PhysioTwin4D uses :class:`physiotwin4d.ConvertVTKToUSD` as the application-level API for VTK-to-USD conversion. Workflows, command-line tools, and experiments should use this class instead of importing -``physiomotion4d.vtk_to_usd`` directly. +``physiotwin4d.vtk_to_usd`` directly. -``physiomotion4d.vtk_to_usd`` remains a public advanced low-level package for +``physiotwin4d.vtk_to_usd`` remains a public advanced low-level package for external users who need file readers, data containers, or direct USD writer primitives. ConvertVTKToUSD ================ -Use :class:`physiomotion4d.ConvertVTKToUSD` for application-level conversion. +Use :class:`physiotwin4d.ConvertVTKToUSD` for application-level conversion. The full API reference is in :doc:`../api/usd/vtk_conversion`. Single File @@ -22,7 +22,7 @@ Single File .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD stage = ConvertVTKToUSD.from_files( data_basename='Heart', @@ -35,7 +35,7 @@ Time Series .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD stage = ConvertVTKToUSD.from_files( data_basename='Heart', @@ -49,7 +49,7 @@ In-Memory Meshes .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD import pyvista as pv meshes = [pv.read(path) for path in vtk_files] @@ -64,7 +64,7 @@ Labeled Meshes with Anatomy Grouping ------------------------------------ When the input has anatomical labels (``mask_ids`` and a ``boundary_labels`` -cell array), pass a :class:`physiomotion4d.SegmentAnatomyBase` instance +cell array), pass a :class:`physiotwin4d.SegmentAnatomyBase` instance through the ``segmenter`` argument so labeled prims are grouped by anatomy type. The output layout becomes: @@ -76,7 +76,7 @@ appears if at least one labeled organ from the input falls into that group. .. code-block:: python - from physiomotion4d import ( + from physiotwin4d import ( ConvertVTKToUSD, SegmentChestTotalSegmentator, ) @@ -155,15 +155,15 @@ that already has a Camera does not produce a duplicate transform op. Anatomy Materials with USDAnatomyTools ======================================= -:class:`physiomotion4d.USDAnatomyTools` applies OmniSurface materials to +:class:`physiotwin4d.USDAnatomyTools` applies OmniSurface materials to labeled meshes after conversion. It reads :class:`AnatomyTaxonomy` from the segmenter to find which prim names map to which group, and looks up the material parameters in its ``render_params`` dict (initialized from the -module-level :data:`physiomotion4d.usd_anatomy_tools.DEFAULT_RENDER_PARAMS`). +module-level :data:`physiotwin4d.usd_anatomy_tools.DEFAULT_RENDER_PARAMS`). .. code-block:: python - from physiomotion4d import USDAnatomyTools + from physiotwin4d import USDAnatomyTools tools = USDAnatomyTools(stage) tools.enhance_meshes(seg) @@ -174,7 +174,7 @@ module-level defaults (affects future instances) or a single instance: .. code-block:: python - from physiomotion4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS + from physiotwin4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS DEFAULT_RENDER_PARAMS["brain"] = { "name": "Brain", @@ -196,6 +196,6 @@ Use the low-level facade only when the high-level class is not appropriate: .. code-block:: python - from physiomotion4d.vtk_to_usd import convert_vtk_file + from physiotwin4d.vtk_to_usd import convert_vtk_file stage = convert_vtk_file('mesh.vtp', 'mesh.usd') diff --git a/docs/developer/utilities.rst b/docs/developer/utilities.rst index a1599a3..93223fb 100644 --- a/docs/developer/utilities.rst +++ b/docs/developer/utilities.rst @@ -2,7 +2,7 @@ Utilities Developer Guide ========================= -PhysioMotion4D utility classes provide reusable operations for images, +PhysioTwin4D utility classes provide reusable operations for images, transforms, contours, and USD files. They are class-based APIs, not module-level free functions. @@ -13,7 +13,7 @@ Transform Tools import itk - from physiomotion4d import TransformTools + from physiotwin4d import TransformTools tools = TransformTools() transform = itk.transformread("forward_transform.hdf") @@ -29,7 +29,7 @@ For PyVista contours: import itk import pyvista as pv - from physiomotion4d import TransformTools + from physiotwin4d import TransformTools mesh = pv.read("heart_t0.vtp") transform = itk.transformread("forward_transform.hdf") @@ -43,7 +43,7 @@ Contour Tools import itk - from physiomotion4d import ContourTools + from physiotwin4d import ContourTools mask = itk.imread("heart_mask.nrrd") contour = ContourTools().extract_contours(mask) @@ -54,7 +54,7 @@ USD Tools .. code-block:: python - from physiomotion4d import USDTools + from physiotwin4d import USDTools tools = USDTools() tools.merge_usd_files( @@ -69,7 +69,7 @@ USD Anatomy Tools from pxr import Usd - from physiomotion4d import USDAnatomyTools + from physiotwin4d import USDAnatomyTools stage = Usd.Stage.Open("anatomy.usd") painter = USDAnatomyTools(stage) diff --git a/docs/developer/workflows.rst b/docs/developer/workflows.rst index e793dc0..b9ac09a 100644 --- a/docs/developer/workflows.rst +++ b/docs/developer/workflows.rst @@ -14,25 +14,25 @@ Current Workflow Mapping * - CLI command - Workflow class - * - ``physiomotion4d-convert-image-to-usd`` - - :class:`physiomotion4d.WorkflowConvertImageToUSD` - * - ``physiomotion4d-convert-image-to-vtk`` - - :class:`physiomotion4d.WorkflowConvertImageToVTK` - * - ``physiomotion4d-convert-vtk-to-usd`` - - :class:`physiomotion4d.WorkflowConvertVTKToUSD` - * - ``physiomotion4d-create-statistical-model`` - - :class:`physiomotion4d.WorkflowCreateStatisticalModel` - * - ``physiomotion4d-fit-statistical-model-to-patient`` - - :class:`physiomotion4d.WorkflowFitStatisticalModelToPatient` - * - ``physiomotion4d-reconstruct-highres-4d-ct`` - - :class:`physiomotion4d.WorkflowReconstructHighres4DCT` + * - ``physiotwin4d-convert-image-to-usd`` + - :class:`physiotwin4d.WorkflowConvertImageToUSD` + * - ``physiotwin4d-convert-image-to-vtk`` + - :class:`physiotwin4d.WorkflowConvertImageToVTK` + * - ``physiotwin4d-convert-vtk-to-usd`` + - :class:`physiotwin4d.WorkflowConvertVTKToUSD` + * - ``physiotwin4d-create-statistical-model`` + - :class:`physiotwin4d.WorkflowCreateStatisticalModel` + * - ``physiotwin4d-fit-statistical-model-to-patient`` + - :class:`physiotwin4d.WorkflowFitStatisticalModelToPatient` + * - ``physiotwin4d-reconstruct-highres-4d-ct`` + - :class:`physiotwin4d.WorkflowReconstructHighres4DCT` Workflow Example ================ .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD workflow = WorkflowConvertImageToUSD( input_filenames=["cardiac_4d.nrrd"], @@ -46,7 +46,7 @@ Workflow Example Adding a Workflow ================= -1. Inherit from :class:`physiomotion4d.PhysioMotion4DBase`. +1. Inherit from :class:`physiotwin4d.PhysioTwin4DBase`. 2. Keep the constructor explicit and typed. 3. Use ``self.log_info()`` and ``self.log_debug()`` for runtime status. 4. Keep file I/O behavior predictable and documented. diff --git a/docs/examples.rst b/docs/examples.rst index 5d155d7..5f403dc 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -2,14 +2,14 @@ Examples ======== -This page provides quick examples for common PhysioMotion4D use cases. For detailed workflow guides, +This page provides quick examples for common PhysioTwin4D use cases. For detailed workflow guides, see the :doc:`cli_scripts/overview` section. .. note:: - **For Production Workflows:** The CLI commands (``physiomotion4d-convert-image-to-usd``, - ``physiomotion4d-create-statistical-model``, ``physiomotion4d-fit-statistical-model-to-patient``) - and their implementations in ``src/physiomotion4d/cli/`` + **For Production Workflows:** The CLI commands (``physiotwin4d-convert-image-to-usd``, + ``physiotwin4d-create-statistical-model``, ``physiotwin4d-fit-statistical-model-to-patient``) + and their implementations in ``src/physiotwin4d/cli/`` are the definitive source for proper library usage, class instantiation, and best practices. The ``experiments/`` directory contains research prototypes that informed development but should @@ -27,7 +27,7 @@ Complete end-to-end cardiac CT processing: .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD # Initialize workflow workflow = WorkflowConvertImageToUSD( @@ -53,7 +53,7 @@ phase images: import itk - from physiomotion4d import RegisterImagesGreedyICON, WorkflowReconstructHighres4DCT + from physiotwin4d import RegisterImagesGreedyICON, WorkflowReconstructHighres4DCT # DirLab-4DCT data is manual-only. Place phase images under ./data/DirLab. phase_dir = Path("./data/DirLab/case1") @@ -82,7 +82,7 @@ Quick segmentation with TotalSegmentator: .. code-block:: python - from physiomotion4d import SegmentChestTotalSegmentatorWithContrast + from physiotwin4d import SegmentChestTotalSegmentatorWithContrast import itk # Load image @@ -114,7 +114,7 @@ Fast GPU-accelerated registration: .. code-block:: python - from physiomotion4d.register_images_icon import RegisterImagesICON + from physiotwin4d.register_images_icon import RegisterImagesICON import itk # Initialize @@ -147,7 +147,7 @@ Register all cardiac phases to reference: .. code-block:: python - from physiomotion4d.register_images_icon import RegisterImagesICON + from physiotwin4d.register_images_icon import RegisterImagesICON import itk import glob @@ -176,7 +176,7 @@ Advanced registration with multiple stages: .. code-block:: python - from physiomotion4d import RegisterImagesANTS + from physiotwin4d import RegisterImagesANTS import itk registerer = RegisterImagesANTS() @@ -201,7 +201,7 @@ Convert VTK mesh sequence to animated USD: .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD import glob # Get VTK files @@ -224,7 +224,7 @@ Combine separate anatomical structures: .. code-block:: python - from physiomotion4d import USDTools + from physiotwin4d import USDTools tools = USDTools() @@ -245,7 +245,7 @@ Add anatomical materials and colors: .. code-block:: python - from physiomotion4d import USDAnatomyTools + from physiotwin4d import USDAnatomyTools from pxr import Usd stage = Usd.Stage.Open("thorax_model.usd") @@ -269,7 +269,7 @@ Warp images using deformation fields: .. code-block:: python - from physiomotion4d import TransformTools + from physiotwin4d import TransformTools import itk tools = TransformTools() @@ -292,7 +292,7 @@ Propagate segmentation contours across time: .. code-block:: python - from physiomotion4d import TransformTools + from physiotwin4d import TransformTools import itk import pyvista as pv @@ -314,7 +314,7 @@ Convert segmentation masks to meshes: .. code-block:: python - from physiomotion4d import ContourTools + from physiotwin4d import ContourTools import itk tools = ContourTools() @@ -390,7 +390,7 @@ Batch process multiple datasets: .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD import glob import os @@ -426,7 +426,7 @@ Segment multiple images in parallel: .. code-block:: python - from physiomotion4d import SegmentChestTotalSegmentatorWithContrast + from physiotwin4d import SegmentChestTotalSegmentatorWithContrast import itk import glob from concurrent.futures import ProcessPoolExecutor @@ -458,7 +458,7 @@ Download Slicer-Heart Dataset .. code-block:: python - from physiomotion4d import DataDownloadTools + from physiotwin4d import DataDownloadTools data_file = DataDownloadTools.DownloadSlicerHeartCTData("data/Slicer-Heart-CT") assert DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT") @@ -473,7 +473,7 @@ Run the supported end-to-end workflow API: .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD workflow = WorkflowConvertImageToUSD( input_filenames=["cardiac_4d.nrrd"], @@ -493,7 +493,7 @@ Mix and match different components: .. code-block:: python - from physiomotion4d import ( + from physiotwin4d import ( SegmentChestTotalSegmentatorWithContrast, RegisterImagesICON, TransformTools, diff --git a/docs/faq.rst b/docs/faq.rst index 617c542..4e2088e 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -2,15 +2,15 @@ FAQ === -Frequently Asked Questions about PhysioMotion4D. +Frequently Asked Questions about PhysioTwin4D. General Questions ================= -What is PhysioMotion4D? +What is PhysioTwin4D? ----------------------- -PhysioMotion4D is a medical imaging package that converts 4D CT scans into dynamic +PhysioTwin4D is a medical imaging package that converts 4D CT scans into dynamic 3D models for visualization in NVIDIA Omniverse. What data formats are supported? @@ -34,7 +34,7 @@ Installation Questions Do I need a GPU? ---------------- -No. A plain ``pip install physiomotion4d`` works without a GPU. At import time +No. A plain ``pip install physiotwin4d`` works without a GPU. At import time a ``UserWarning`` is emitted (visible by default in all standard Python runs): .. code-block:: text @@ -42,7 +42,7 @@ a ``UserWarning`` is emitted (visible by default in all standard Python runs): CuPy is not installed — GPU acceleration is unavailable and processing will be slow. Re-install with uv to get CuPy and CUDA-enabled PyTorch in one step (pip alone will not select the correct CUDA wheel): - uv pip install 'physiomotion4d[cuda13]' # CUDA 13 + uv pip install 'physiotwin4d[cuda13]' # CUDA 13 CPU-only mode is suitable for evaluation and small datasets. For production workloads an NVIDIA GPU is strongly recommended. @@ -54,7 +54,7 @@ CUDA 13 is supported. Install the CUDA 13 extra for GPU acceleration: .. code-block:: bash - uv pip install "physiomotion4d[cuda13]" + uv pip install "physiotwin4d[cuda13]" The extra installs CuPy. In uv-managed source environments, PyTorch, torchvision, and torchaudio are sourced from @@ -105,5 +105,5 @@ More Questions? * Check the :doc:`cli_scripts/heart_gated_ct` * Browse :doc:`examples` -* Open an issue on `GitHub `_ +* Open an issue on `GitHub `_ diff --git a/docs/index.rst b/docs/index.rst index 3056c15..2568cf9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,129 +1,129 @@ -.. PhysioMotion4D documentation master file +.. PhysioTwin4D documentation master file -.. title:: PhysioMotion4D Documentation +.. title:: PhysioTwin4D Documentation .. raw:: html -
-
+
+
NVIDIA logo
-

PhysioMotion4D tutorials

+

PhysioTwin4D tutorials

Build animated medical USD workflows for NVIDIA Omniverse

- PhysioMotion4D converts 3D and 4D medical scans into dynamic OpenUSD + PhysioTwin4D converts 3D and 4D medical scans into dynamic OpenUSD assets for NVIDIA Omniverse. Start with the tutorial cards, then use the documentation sections below for installation, CLI workflows, API references, developer notes, and contribution guidance.

-

Version {{ pm4d_project_version }}

+

Version {{ pt4d_project_version }}

-
- - 01 +
+ + 01

Heart-Gated CT to Animated USD

Convert cardiac 4D CT frames into registered contours and an animated OpenUSD model.

- Slicer-Heart-CT + Slicer-Heart-CT
- - 02 + + 02

CT Segmentation to VTK Surfaces

Segment one CT phase and export patient anatomy as VTK PolyData surfaces.

- Slicer-Heart-CT + Slicer-Heart-CT
- - 03 + + 03

Create a PCA Shape Model

Build a statistical shape model from aligned cardiac meshes.

- KCL-Heart-Model + KCL-Heart-Model
- - 04 + + 04

Fit Statistical Model to Patient

Fit a PCA heart model to patient-specific anatomy for model-based reconstruction.

- Tutorial 3 output + Tutorial 3 output
- - 05 + + 05

VTK Surface Series to Animated USD

Convert VTK meshes into a time-sampled USD scene for Omniverse playback.

- Tutorial 2 output + Tutorial 2 output
- - 06 + + 06

Reconstruct High-Resolution 4D CT

Register respiratory CT phases and reconstruct a higher-resolution 4D volume series.

- DirLab-4DCT + DirLab-4DCT
- - 08 + + 08

Fit the Cardiac SSM and Propagate Through Gated Phases

Fit a PCA heart model to the reference phase and propagate it to every gated phase with ICON registration.

- Bring your own cardiac data + Bring your own cardiac data
- - 09 + + 09

Train a PhysicsNeMo Cardiac Stage Model

Train a PhysicsNeMo MeshGraphNet (9a) or MLP (9b) to predict cardiac meshes at requested stages.

- Tutorial 8 output + Tutorial 8 output
- - 10 + + 10

Predict and Evaluate Cardiac Surfaces

Load a Tutorial 9 checkpoint and predict cardiac surfaces at gated phases or caller-specified stages.

- Tutorial 9a / 9b output + Tutorial 9a / 9b output
-
-
-

Documentation

+
+
+

Documentation

Explore the rest of the docs

-
- +
+

Installation

-

Set up PhysioMotion4D with CUDA extras, CPU-only options, and required system tools.

+

Set up PhysioTwin4D with CUDA extras, CPU-only options, and required system tools.

- +

Getting Started

Run your first workflow and understand the basic CT-to-USD processing path.

- +

Examples

Review focused usage patterns for common cardiac, lung, segmentation, and USD tasks.

- +

CLI Workflows

Use production command-line workflows for conversion, reconstruction, modeling, and USD export.

- +

Isaac for Healthcare

-

Find PhysioMotion4D workflows and assets for Isaac for Healthcare use cases.

+

Find PhysioTwin4D workflows and assets for Isaac for Healthcare use cases.

- +

API Reference

Browse classes and modules for workflows, segmentation, registration, USD, and utilities.

- +

Developer Docs

Understand architecture, extension points, coordinate transforms, and implementation boundaries.

- +

Architecture

Trace the actual workflow classes and data flow from CT inputs to USD outputs.

- +

Contributing

Follow repository conventions for code style, testing, documentation, and pull requests.

- +

Testing

Run the fast test suite, data-gated tutorial tests, and regression checks.

- +

Troubleshooting

Diagnose environment, data, segmentation, registration, and USD playback issues.

@@ -213,7 +213,7 @@ per-tutorial implementation details. Clinical Use ============ -Not validated for clinical use. PhysioMotion4D {{ pm4d_project_version }} beta +Not validated for clinical use. PhysioTwin4D {{ pt4d_project_version }} beta is a research and visualization toolkit, not a medical device. Do not use it for diagnosis, treatment planning, or clinical decision-making. diff --git a/docs/installation.rst b/docs/installation.rst index 962f867..27c482c 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -2,7 +2,7 @@ Installation ============ -This guide covers the installation of PhysioMotion4D and its dependencies. +This guide covers the installation of PhysioTwin4D and its dependencies. Prerequisites ============= @@ -19,7 +19,7 @@ System Requirements Software Dependencies --------------------- -PhysioMotion4D relies on several key packages: +PhysioTwin4D relies on several key packages: * **Medical Imaging**: ITK, MONAI, nibabel, PyVista * **AI/ML**: PyTorch, CuPy (CUDA 13), transformers, MONAI @@ -33,13 +33,13 @@ Installation Methods Method 1: Install from PyPI (Recommended) ------------------------------------------ -The simplest way to install PhysioMotion4D is from PyPI. +The simplest way to install PhysioTwin4D is from PyPI. CPU-only PyPI install (evaluation / no GPU): .. code-block:: bash - pip install physiomotion4d + pip install physiotwin4d This works immediately. CuPy is absent, so a ``UserWarning`` is emitted at import time (visible by default in all standard Python runs): @@ -49,13 +49,13 @@ import time (visible by default in all standard Python runs): CuPy is not installed — GPU acceleration is unavailable and processing will be slow. Re-install with uv to get CuPy and CUDA-enabled PyTorch in one step (pip alone will not select the correct CUDA wheel): - uv pip install 'physiomotion4d[cuda13]' # CUDA 13 + uv pip install 'physiotwin4d[cuda13]' # CUDA 13 CUDA 13 install (recommended for production): .. code-block:: bash - uv pip install "physiomotion4d[cuda13]" + uv pip install "physiotwin4d[cuda13]" The ``[cuda13]`` extra installs CuPy. In uv-managed source environments, PyTorch, torchvision, and torchaudio resolve from the CUDA 13.0 PyTorch wheel @@ -70,8 +70,8 @@ For development or to get the latest features: .. code-block:: bash - git clone https://github.com/Project-MONAI/physiomotion4d.git - cd physiomotion4d + git clone https://github.com/Project-MONAI/physiotwin4d.git + cd physiotwin4d **Step 2: Create virtual environment** @@ -97,7 +97,7 @@ For development or to get the latest features: pip install uv -**Step 4: Install PhysioMotion4D** +**Step 4: Install PhysioTwin4D** Default uv-managed source install: @@ -122,7 +122,7 @@ To install development dependencies (testing, linting, formatting): .. code-block:: bash - pip install physiomotion4d[dev] + pip install physiotwin4d[dev] This includes: @@ -132,7 +132,7 @@ This includes: * **pre-commit** (git hooks for automatic checks) .. note:: - As of 2026, PhysioMotion4D uses Ruff as the primary linter and formatter, + As of 2026, PhysioTwin4D uses Ruff as the primary linter and formatter, replacing the previous black, isort, flake8, and pylint tools for improved speed and simplicity. @@ -143,7 +143,7 @@ To build documentation locally: .. code-block:: bash - pip install physiomotion4d[docs] + pip install physiotwin4d[docs] Testing Dependencies -------------------- @@ -152,38 +152,38 @@ To run tests: .. code-block:: bash - pip install physiomotion4d[test] + pip install physiotwin4d[test] Verify Installation =================== -After installation, verify that PhysioMotion4D is correctly installed: +After installation, verify that PhysioTwin4D is correctly installed: .. code-block:: python - import physiomotion4d - from physiomotion4d import WorkflowConvertImageToUSD + import physiotwin4d + from physiotwin4d import WorkflowConvertImageToUSD - print(f"PhysioMotion4D version: {physiomotion4d.__version__}") + print(f"PhysioTwin4D version: {physiotwin4d.__version__}") print(WorkflowConvertImageToUSD.__name__) Expected output: .. code-block:: text - PhysioMotion4D version: {{ pm4d_project_version }} + PhysioTwin4D version: {{ pt4d_project_version }} WorkflowConvertImageToUSD Command-Line Tools ================== -PhysioMotion4D provides command-line interfaces that should be available after installation: +PhysioTwin4D provides command-line interfaces that should be available after installation: .. code-block:: bash # Check CLI is available - physiomotion4d --help - physiomotion4d-convert-image-to-usd --help + physiotwin4d --help + physiotwin4d-convert-image-to-usd --help GPU Setup ========= @@ -196,7 +196,7 @@ extra: * **CUDA 13** — installed when you use the ``[cuda13]`` extra (recommended) -A plain ``pip install physiomotion4d`` installs a CPU-only build. It runs +A plain ``pip install physiotwin4d`` installs a CPU-only build. It runs without error but emits a ``UserWarning`` at import time and will be significantly slower than a GPU-enabled install. @@ -230,7 +230,7 @@ Common Issues **Issue: CUDA out of memory** -Solution: Reduce batch sizes or process smaller images. Most PhysioMotion4D functions work with limited GPU memory. +Solution: Reduce batch sizes or process smaller images. Most PhysioTwin4D functions work with limited GPU memory. **Issue: Import errors for ITK or VTK** @@ -263,7 +263,7 @@ Getting Help If you encounter issues: 1. Check the :doc:`troubleshooting` guide -2. Search `GitHub Issues `_ +2. Search `GitHub Issues `_ 3. Open a new issue with: * Python version @@ -274,7 +274,7 @@ If you encounter issues: Next Steps ========== -* Continue to :doc:`quickstart` for your first PhysioMotion4D workflow +* Continue to :doc:`quickstart` for your first PhysioTwin4D workflow * Explore :doc:`examples` for common use cases * Read :doc:`cli_scripts/overview` for detailed command-line workflows diff --git a/docs/isaac_for_healthcare.rst b/docs/isaac_for_healthcare.rst index b860a96..0680705 100644 --- a/docs/isaac_for_healthcare.rst +++ b/docs/isaac_for_healthcare.rst @@ -1,20 +1,20 @@ Isaac for Healthcare ==================== -Use these resources to create, inspect, and download PhysioMotion4D assets for +Use these resources to create, inspect, and download PhysioTwin4D assets for Isaac for Healthcare workflows. .. raw:: html -
-
- +
+
diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 09f3d75..a5d2ee0 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -2,12 +2,12 @@ Quick Start =========== -This guide will help you get started with PhysioMotion4D quickly. +This guide will help you get started with PhysioTwin4D quickly. .. warning:: - **Not validated for clinical use.** PhysioMotion4D - {{ pm4d_project_version }} beta is a research and visualization toolkit, not + **Not validated for clinical use.** PhysioTwin4D + {{ pt4d_project_version }} beta is a research and visualization toolkit, not a medical device. Do not use it for diagnosis, treatment planning, or clinical decision-making. @@ -34,7 +34,7 @@ After preparing the Slicer-Heart-CT data, run the first two tutorials: python tutorials/tutorial_02_ct_to_vtk.py Tutorial paths are defined near the top of each script. To use different paths, -edit the script constants or use the installed ``physiomotion4d-*`` CLI commands. +edit the script constants or use the installed ``physiotwin4d-*`` CLI commands. See ``tutorials/README.md`` for dataset download instructions and the recommended run order. @@ -57,7 +57,7 @@ Prerequisites Before starting, ensure you have: -* PhysioMotion4D installed (see :doc:`installation`) +* PhysioTwin4D installed (see :doc:`installation`) * NVIDIA GPU with CUDA 13 - recommended for production performance; see :doc:`installation` for the ``[cuda13]`` extra. A CPU-only PyPI install works for evaluation but is slow. * 4D cardiac CT data or access to sample datasets @@ -73,9 +73,9 @@ CUDA-capable GPU are required for practical runtime. .. code-block:: bash - python -c "from physiomotion4d import DataDownloadTools; DataDownloadTools.DownloadSlicerHeartCTData('data/test')" + python -c "from physiotwin4d import DataDownloadTools; DataDownloadTools.DownloadSlicerHeartCTData('data/test')" - physiomotion4d-convert-image-to-usd data/test/TruncalValve_4DCT.seq.nrrd \ + physiotwin4d-convert-image-to-usd data/test/TruncalValve_4DCT.seq.nrrd \ --registration-method ICON \ --output-dir output/quickstart \ --project-name slicer_heart_quickstart @@ -88,13 +88,13 @@ The fastest way to process cardiac CT data is using the command-line interface: .. code-block:: bash # Process a single 4D cardiac CT file - physiomotion4d-convert-image-to-usd cardiac_4d.nrrd --contrast --output-dir ./results + physiotwin4d-convert-image-to-usd cardiac_4d.nrrd --contrast --output-dir ./results # Process multiple time frames - physiomotion4d-convert-image-to-usd frame_*.nrrd --contrast --project-name patient_001 + physiotwin4d-convert-image-to-usd frame_*.nrrd --contrast --project-name patient_001 # With custom settings - physiomotion4d-convert-image-to-usd cardiac.nrrd \ + physiotwin4d-convert-image-to-usd cardiac.nrrd \ --contrast \ --reference-image ref.mha \ --registration-iterations 50 \ @@ -109,7 +109,7 @@ For more control, use the Python API: .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD **Step 2: Initialize with your data** @@ -146,7 +146,7 @@ For more control over individual steps: .. code-block:: python - from physiomotion4d import RegisterImagesICON, WorkflowConvertImageToUSD + from physiotwin4d import RegisterImagesICON, WorkflowConvertImageToUSD # Initialize workflow workflow = WorkflowConvertImageToUSD( @@ -168,7 +168,7 @@ If you only need segmentation: .. code-block:: python - from physiomotion4d import SegmentChestTotalSegmentatorWithContrast + from physiotwin4d import SegmentChestTotalSegmentatorWithContrast import itk # Initialize segmenter (use SegmentChestTotalSegmentator for non-contrast studies) @@ -195,7 +195,7 @@ For standalone registration: .. code-block:: python - from physiomotion4d.register_images_icon import RegisterImagesICON + from physiotwin4d.register_images_icon import RegisterImagesICON import itk # Initialize registration @@ -223,7 +223,7 @@ Convert VTK time series to USD: .. code-block:: python - from physiomotion4d import ConvertVTKToUSD + from physiotwin4d import ConvertVTKToUSD vtk_files = [f"heart_frame_{i:03d}.vtp" for i in range(10)] time_codes = [float(i) for i in range(len(vtk_files))] @@ -242,7 +242,7 @@ Download Sample Cardiac CT Data .. code-block:: python - from physiomotion4d import DataDownloadTools + from physiotwin4d import DataDownloadTools data_file = DataDownloadTools.DownloadSlicerHeartCTData("sample_data") assert DataDownloadTools.VerifySlicerHeartCTData("sample_data") @@ -251,7 +251,7 @@ DirLab-4DCT data is manual-only; see ``data/README.md`` before running the high-resolution 4D CT reconstruction tutorial. Tutorials 8-10 are bring-your-own-data cardiac tutorials; see :doc:`tutorials` for their dataset layout. Tutorials 9a/9b/10a/10b additionally require the optional -``physicsnemo`` extra (``pip install "physiomotion4d[physicsnemo]"``); +``physicsnemo`` extra (``pip install "physiotwin4d[physicsnemo]"``); PhysicsNeMo itself requires Python >= 3.11. Visualizing Results @@ -302,9 +302,9 @@ Now that you've completed your first workflow: **About CLI Commands and Experiments:** * **CLI Commands** ⭐ **PRIMARY RESOURCE** - Production-ready workflows with proper class usage - (``physiomotion4d-convert-image-to-usd``, ``physiomotion4d-create-statistical-model``, - ``physiomotion4d-fit-statistical-model-to-patient``). - See ``src/physiomotion4d/cli/`` for implementation details. + (``physiotwin4d-convert-image-to-usd``, ``physiotwin4d-create-statistical-model``, + ``physiotwin4d-fit-statistical-model-to-patient``). + See ``src/physiotwin4d/cli/`` for implementation details. * **experiments/** - Research prototypes and design explorations. These demonstrate conceptual approaches for adapting workflows to new anatomical regions and digital twin applications, diff --git a/docs/references.rst b/docs/references.rst index 43289be..29b134c 100644 --- a/docs/references.rst +++ b/docs/references.rst @@ -2,21 +2,21 @@ References =========== -Academic papers, datasets, and resources related to PhysioMotion4D. +Academic papers, datasets, and resources related to PhysioTwin4D. Software Citations ================== -If you use PhysioMotion4D in your research, please cite: +If you use PhysioTwin4D in your research, please cite: .. code-block:: bibtex - @software{physiomotion4d, + @software{physiotwin4d, author = {Aylward, Stephen R.}, - title = {PhysioMotion4D: Medical Imaging to Omniverse}, + title = {PhysioTwin4D: Medical Imaging to Omniverse}, year = {2025}, publisher = {GitHub}, - url = {https://github.com/Project-MONAI/physiomotion4d} + url = {https://github.com/Project-MONAI/physiotwin4d} } Related Publications diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index b75c798..ac312ee 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -2,7 +2,7 @@ Troubleshooting =============== -Common issues and solutions for PhysioMotion4D. +Common issues and solutions for PhysioTwin4D. Installation Issues =================== @@ -31,7 +31,7 @@ version than the one present on the system. .. code-block:: bash - uv pip install "physiomotion4d[cuda13]" + uv pip install "physiotwin4d[cuda13]" The extra installs CuPy. In uv-managed source environments, PyTorch resolves from the CUDA 13.0 wheel index. @@ -43,7 +43,7 @@ Verify the active CUDA version before reinstalling: nvidia-smi # shows driver and CUDA version .. note:: - If you have no NVIDIA GPU, a plain ``pip install physiomotion4d`` installs a + If you have no NVIDIA GPU, a plain ``pip install physiotwin4d`` installs a CPU-only build. CuPy is absent and a ``UserWarning`` is emitted at import time. CPU execution of all operations is supported but will be significantly slower than a GPU-enabled install. @@ -57,7 +57,7 @@ Import Errors .. code-block:: bash - pip install --upgrade physiomotion4d + pip install --upgrade physiotwin4d Processing Issues ================= @@ -75,7 +75,7 @@ Poor Segmentation Quality .. code-block:: python - from physiomotion4d import ( + from physiotwin4d import ( SegmentChestTotalSegmentatorWithContrast, WorkflowConvertImageToUSD, ) @@ -100,7 +100,7 @@ Registration Not Converging .. code-block:: bash - physiomotion4d-convert-image-to-usd cardiac_4d.nrrd --registration-method Greedy + physiotwin4d-convert-image-to-usd cardiac_4d.nrrd --registration-method Greedy 3. Check image orientation and spacing @@ -148,7 +148,7 @@ Slow Processing **Solutions**: -1. Install ``physiomotion4d[cuda13]`` with uv for CUDA acceleration. +1. Install ``physiotwin4d[cuda13]`` with uv for CUDA acceleration. 2. Reduce ``--registration-iterations`` during exploratory runs. 3. Run tutorial workflows with reduced frame counts where supported. @@ -158,7 +158,7 @@ Getting Help If you still have issues: 1. Check :doc:`faq` -2. Search `GitHub Issues `_ +2. Search `GitHub Issues `_ 3. Open a new issue with: * Python version diff --git a/docs/tutorials.rst b/docs/tutorials.rst index 001165c..1ebd50d 100644 --- a/docs/tutorials.rst +++ b/docs/tutorials.rst @@ -4,11 +4,11 @@ Tutorials .. raw:: html -
-
+
+
NVIDIA logo
-

PhysioMotion4D tutorials

+

PhysioTwin4D tutorials

Build animated medical USD workflows for NVIDIA Omniverse

Nine focused tutorials walk through CT segmentation, registration, @@ -18,60 +18,60 @@ Tutorials

-
- - 01 +
+ + 01

Heart-Gated CT to Animated USD

Convert cardiac 4D CT frames into registered contours and an animated OpenUSD model.

- Slicer-Heart-CT + Slicer-Heart-CT
- - 02 + + 02

CT Segmentation to VTK Surfaces

Segment one CT phase and export patient anatomy as VTK PolyData surfaces.

- Slicer-Heart-CT + Slicer-Heart-CT
- - 03 + + 03

Create a PCA Shape Model

Build a statistical shape model from aligned cardiac meshes.

- KCL-Heart-Model + KCL-Heart-Model
- - 04 + + 04

Fit Statistical Model to Patient

Fit a PCA heart model to patient-specific anatomy for model-based reconstruction.

- Tutorial 3 output + Tutorial 3 output
- - 05 + + 05

VTK Surface Series to Animated USD

Convert VTK meshes into a time-sampled USD scene for Omniverse playback.

- Tutorial 2 output + Tutorial 2 output
- - 06 + + 06

Reconstruct High-Resolution 4D CT

Register respiratory CT phases and reconstruct a higher-resolution 4D volume series.

- DirLab-4DCT + DirLab-4DCT
- - 08 + + 08

Fit the Cardiac SSM and Propagate Through Gated Phases

Fit a PCA heart model to the reference phase and propagate it to every gated phase with ICON registration.

- Bring your own cardiac data + Bring your own cardiac data
- - 09 + + 09

Train a PhysicsNeMo Cardiac Stage Model

Train a PhysicsNeMo MeshGraphNet (9a) or MLP (9b) to predict cardiac meshes at requested stages.

- Tutorial 8 output + Tutorial 8 output
- - 10 + + 10

Predict and Evaluate Cardiac Surfaces

Load a Tutorial 9 checkpoint and predict cardiac surfaces at gated phases or caller-specified stages.

- Tutorial 9a / 9b output + Tutorial 9a / 9b output
@@ -81,7 +81,7 @@ Recommended Run Order Tutorials are ``# %%`` percent-cell Python scripts. Each script defines its data and output paths near the top, using repository ``data/`` and ``output/`` directories by default. Edit those constants for tutorial exploration, or use -the installed ``physiomotion4d-*`` CLI commands when you need command-line path +the installed ``physiotwin4d-*`` CLI commands when you need command-line path arguments. 1. Run Tutorials 1 and 2 after preparing Slicer-Heart-CT data. @@ -223,7 +223,7 @@ Outputs Tutorials 8-10 form the cardiac mesh stage-prediction pipeline and are **bring-your-own-data**: unlike Tutorials 1-6 they do not use the repository ``data/`` directory or a downloadable sample. Their path constants point at a - local ``D:/PhysioMotion4D/`` cardiac layout (gated CT, labelmaps, the KCL + local ``D:/PhysioTwin4D/`` cardiac layout (gated CT, labelmaps, the KCL volume PCA model, and ICON weights); edit those constants to match your own data. The former DirLab lung-lobe PCA tutorial (number 7) has been removed; numbering continues at 8. @@ -240,7 +240,7 @@ Workflow Dataset Bring your own cardiac gated CT, labelmaps, KCL volume PCA model, and ICON - weights under ``D:/PhysioMotion4D/``. + weights under ``D:/PhysioTwin4D/``. Run .. code-block:: bash @@ -267,7 +267,7 @@ Dataset Extra install PhysicsNeMo is an optional dependency. Install with - ``pip install "physiomotion4d[physicsnemo]"`` (requires Python >= 3.11). The + ``pip install "physiotwin4d[physicsnemo]"`` (requires Python >= 3.11). The MeshGraphNet variant also requires ``torch-geometric``. Run diff --git a/experiments/Colormap-VTK_To_USD/colormap_vtk_to_usd.py b/experiments/Colormap-VTK_To_USD/colormap_vtk_to_usd.py index cde180a..8098be6 100644 --- a/experiments/Colormap-VTK_To_USD/colormap_vtk_to_usd.py +++ b/experiments/Colormap-VTK_To_USD/colormap_vtk_to_usd.py @@ -19,7 +19,7 @@ import numpy as np import pyvista as pv -from physiomotion4d import ConvertVTKToUSD +from physiotwin4d import ConvertVTKToUSD _HERE = Path(__file__).parent @@ -28,7 +28,7 @@ output_dir = _HERE / "output" output_dir.mkdir(exist_ok=True) -print("PhysioMotion4D Colormap Examples") +print("PhysioTwin4D Colormap Examples") print("=" * 50) diff --git a/experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.py b/experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.py index c05915c..f130131 100644 --- a/experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.py +++ b/experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.py @@ -29,13 +29,13 @@ import re from pathlib import Path -from physiomotion4d import ConvertVTKToUSD +from physiotwin4d import ConvertVTKToUSD # Use as a test -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # Import USDTools for post-processing colormap -from physiomotion4d.usd_tools import USDTools +from physiotwin4d.usd_tools import USDTools # %% [markdown] # ## 1. Discover and Organize Time-Series Files diff --git a/experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.py b/experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.py index 4d6cae6..c3ae1ee 100644 --- a/experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.py +++ b/experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.py @@ -3,7 +3,7 @@ from pathlib import Path -from physiomotion4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD +from physiotwin4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD _HERE = Path(__file__).parent diff --git a/experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.py b/experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.py index 5722516..2c32d79 100644 --- a/experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.py +++ b/experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.py @@ -29,11 +29,11 @@ import re from pathlib import Path -from physiomotion4d import ConvertVTKToUSD -from physiomotion4d.test_tools import TestTools +from physiotwin4d import ConvertVTKToUSD +from physiotwin4d.test_tools import TestTools # Import USDTools for post-processing colormap -from physiomotion4d.usd_tools import USDTools +from physiotwin4d.usd_tools import USDTools # %% [markdown] # ## 1. Discover and Organize Time-Series Files diff --git a/experiments/Convert_VTK_To_USD/convert_vtk_to_usd_using_class.py b/experiments/Convert_VTK_To_USD/convert_vtk_to_usd_using_class.py index 6298ccb..0b47e18 100644 --- a/experiments/Convert_VTK_To_USD/convert_vtk_to_usd_using_class.py +++ b/experiments/Convert_VTK_To_USD/convert_vtk_to_usd_using_class.py @@ -30,7 +30,7 @@ import pyvista as pv from pxr import Usd, UsdGeom, UsdShade -from physiomotion4d import ContourTools, ConvertVTKToUSD +from physiotwin4d import ContourTools, ConvertVTKToUSD # Configure logging logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") diff --git a/experiments/Heart-Create_Statistical_Model/1-input_meshes_to_input_surfaces.py b/experiments/Heart-Create_Statistical_Model/1-input_meshes_to_input_surfaces.py index 3f2c0a4..3762872 100644 --- a/experiments/Heart-Create_Statistical_Model/1-input_meshes_to_input_surfaces.py +++ b/experiments/Heart-Create_Statistical_Model/1-input_meshes_to_input_surfaces.py @@ -13,7 +13,7 @@ import pyvista as pv -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools _HERE = Path(__file__).parent diff --git a/experiments/Heart-Create_Statistical_Model/2-input_surfaces_to_surfaces_aligned.py b/experiments/Heart-Create_Statistical_Model/2-input_surfaces_to_surfaces_aligned.py index f0cc516..2cbe175 100644 --- a/experiments/Heart-Create_Statistical_Model/2-input_surfaces_to_surfaces_aligned.py +++ b/experiments/Heart-Create_Statistical_Model/2-input_surfaces_to_surfaces_aligned.py @@ -22,9 +22,9 @@ import pandas as pd import pyvista as pv -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.test_tools import TestTools -from physiomotion4d.register_models_icp import RegisterModelsICP +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.test_tools import TestTools +from physiotwin4d.register_models_icp import RegisterModelsICP _HERE = Path(__file__).parent diff --git a/experiments/Heart-Create_Statistical_Model/3-registration_based_correspondence.py b/experiments/Heart-Create_Statistical_Model/3-registration_based_correspondence.py index 50a3c57..a27d628 100644 --- a/experiments/Heart-Create_Statistical_Model/3-registration_based_correspondence.py +++ b/experiments/Heart-Create_Statistical_Model/3-registration_based_correspondence.py @@ -27,9 +27,9 @@ from pathlib import Path -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.test_tools import TestTools -from physiomotion4d.register_models_distance_maps import RegisterModelsDistanceMaps +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.test_tools import TestTools +from physiotwin4d.register_models_distance_maps import RegisterModelsDistanceMaps _HERE = Path(__file__).parent diff --git a/experiments/Heart-Create_Statistical_Model/4-surfaces_aligned_correspond_to_pca_inputs.py b/experiments/Heart-Create_Statistical_Model/4-surfaces_aligned_correspond_to_pca_inputs.py index 59eb65d..92fde1b 100644 --- a/experiments/Heart-Create_Statistical_Model/4-surfaces_aligned_correspond_to_pca_inputs.py +++ b/experiments/Heart-Create_Statistical_Model/4-surfaces_aligned_correspond_to_pca_inputs.py @@ -6,8 +6,8 @@ import numpy as np import pyvista as pv -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.test_tools import TestTools +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.test_tools import TestTools _HERE = Path(__file__).parent diff --git a/experiments/Heart-Create_Statistical_Model/5-compute_pca_model.py b/experiments/Heart-Create_Statistical_Model/5-compute_pca_model.py index 773988d..2ddaf44 100644 --- a/experiments/Heart-Create_Statistical_Model/5-compute_pca_model.py +++ b/experiments/Heart-Create_Statistical_Model/5-compute_pca_model.py @@ -22,7 +22,7 @@ from sklearn.decomposition import PCA # SparsePCA, ... -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools _HERE = Path(__file__).parent diff --git a/experiments/Heart-Create_Statistical_Model/README.md b/experiments/Heart-Create_Statistical_Model/README.md index d4f642a..4e2c7bf 100644 --- a/experiments/Heart-Create_Statistical_Model/README.md +++ b/experiments/Heart-Create_Statistical_Model/README.md @@ -146,7 +146,7 @@ After completing this experiment, you will have generated files in `kcl-heart-mo The outputs from this experiment are used in the `Heart-Statistical_Model_To_Patient` experiment: ```python -from physiomotion4d import WorkflowFitStatisticalModelToPatient +from physiotwin4d import WorkflowFitStatisticalModelToPatient # Use PCA model from this experiment workflow = WorkflowFitStatisticalModelToPatient( @@ -163,11 +163,11 @@ registered_mesh = workflow.run_workflow() ## Requirements ### Software -- Python 3.11+ with PhysioMotion4D installed +- Python 3.11+ with PhysioTwin4D installed - VS Code or Cursor with the Python extension for cell-by-cell execution (optional; scripts also run end-to-end as plain Python) -- ITK, VTK, PyVista (included with PhysioMotion4D) -- picsl-greedy and ICON (included with PhysioMotion4D) +- ITK, VTK, PyVista (included with PhysioTwin4D) +- picsl-greedy and ICON (included with PhysioTwin4D) - scikit-learn for PCA computation ### Data @@ -200,8 +200,8 @@ For ICON registration: - **KCL Dataset**: [https://zenodo.org/records/4590294](https://zenodo.org/records/4590294) - **Greedy Documentation**: [https://greedy.readthedocs.io/](https://greedy.readthedocs.io/) -- **PhysioMotion4D Documentation**: See main repository README and API documentation -- **Issues**: Report bugs or request features on the PhysioMotion4D GitHub repository +- **PhysioTwin4D Documentation**: See main repository README and API documentation +- **Issues**: Report bugs or request features on the PhysioTwin4D GitHub repository ## Troubleshooting @@ -227,7 +227,7 @@ For ICON registration: - If ICON deformable quality is poor, increase `icon_iterations` in the `register()` call ### Import Errors -- Ensure all PhysioMotion4D dependencies are installed +- Ensure all PhysioTwin4D dependencies are installed - Check Greedy is available: `python -c "from picsl_greedy import Greedy3D; print('ok')"` - Reinstall environment if needed: `pip install -e .` in repository root diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/0-cardiacGatedCT_segment_and_landmark.py b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/0-cardiacGatedCT_segment_and_landmark.py index 6697b0e..e37fd54 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/0-cardiacGatedCT_segment_and_landmark.py +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/0-cardiacGatedCT_segment_and_landmark.py @@ -10,7 +10,7 @@ # `gated_nii//` directory by the first six filename characters. # # Segmentation labelmaps and landmarks are written to: -# `d:/PhysioMotion4D/duke_data/simple_ascardio//` +# `d:/PhysioTwin4D/duke_data/simple_ascardio//` # # Output files follow the input stem: # - `_labelmap.nii.gz` @@ -23,16 +23,16 @@ import itk -from physiomotion4d import SegmentHeartSimpleware -from physiomotion4d.landmark_tools import LandmarkTools +from physiotwin4d import SegmentHeartSimpleware +from physiotwin4d.landmark_tools import LandmarkTools # %% # Discover data (mirrors recon_4d.py) ######################################################## -ref_data_dir = "d:/PhysioMotion4D/duke_data/ref_images" -src_data_dir_base = "d:/PhysioMotion4D/duke_data/gated_nii" -segmentation_dir_base = "d:/PhysioMotion4D/duke_data/simple_ascardio" +ref_data_dir = "d:/PhysioTwin4D/duke_data/ref_images" +src_data_dir_base = "d:/PhysioTwin4D/duke_data/gated_nii" +segmentation_dir_base = "d:/PhysioTwin4D/duke_data/simple_ascardio" ref_files = [ os.path.join(ref_data_dir, f) diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/1-initial_registration.py b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/1-initial_registration.py index 74ad70a..93213e1 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/1-initial_registration.py +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/1-initial_registration.py @@ -15,17 +15,17 @@ import itk import numpy as np -from physiomotion4d.labelmap_tools import LabelmapTools -from physiomotion4d.landmark_tools import LandmarkTools -from physiomotion4d.register_images_ants import RegisterImagesANTS -from physiomotion4d.register_images_greedy import RegisterImagesGreedy -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.labelmap_tools import LabelmapTools +from physiotwin4d.landmark_tools import LandmarkTools +from physiotwin4d.register_images_ants import RegisterImagesANTS +from physiotwin4d.register_images_greedy import RegisterImagesGreedy +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.transform_tools import TransformTools # %% -ref_data_dir = Path("d:/PhysioMotion4D/duke_data/ref_images") -src_data_dir_base = Path("d:/PhysioMotion4D/duke_data/gated_nii") -segmentation_dir_base = Path("d:/PhysioMotion4D/duke_data/simple_ascardio") +ref_data_dir = Path("d:/PhysioTwin4D/duke_data/ref_images") +src_data_dir_base = Path("d:/PhysioTwin4D/duke_data/gated_nii") +segmentation_dir_base = Path("d:/PhysioTwin4D/duke_data/simple_ascardio") use_mask_list = [False, False] use_labelmap_list = [False, True] diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/2-finetune_icon.py b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/2-finetune_icon.py index a9e5073..728bcbc 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/2-finetune_icon.py +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/2-finetune_icon.py @@ -28,16 +28,16 @@ from pathlib import Path from typing import Optional -from physiomotion4d import WorkflowFineTuneICONRegistration -from physiomotion4d.labelmap_tools import LabelmapTools +from physiotwin4d import WorkflowFineTuneICONRegistration +from physiotwin4d.labelmap_tools import LabelmapTools # %% [markdown] # ## 1. Configure data, output locations, and the train/test split # %% -ref_data_dir = Path("d:/PhysioMotion4D/duke_data/ref_images") -src_data_dir_base = Path("d:/PhysioMotion4D/duke_data/gated_nii") -labelmap_dir_base = Path("d:/PhysioMotion4D/duke_data/simple_ascardio") +ref_data_dir = Path("d:/PhysioTwin4D/duke_data/ref_images") +src_data_dir_base = Path("d:/PhysioTwin4D/duke_data/gated_nii") +labelmap_dir_base = Path("d:/PhysioTwin4D/duke_data/simple_ascardio") # Where the workflow writes the dataset JSON, YAML config, derived masks, and # the uniGradICON ``checkpoints/`` tree. experiment_dir resolves to @@ -52,8 +52,8 @@ # ``. Those init frames are merged into each patient's training # group below (section 4b). initial_registration_dirs = [ - Path("d:/PhysioMotion4D/duke_data/greedy_registrations/results_l/greedy_40.40.10"), - Path("d:/PhysioMotion4D/duke_data/greedy_registrations/results_raw/greedy_80.40.5"), + Path("d:/PhysioTwin4D/duke_data/greedy_registrations/results_l/greedy_40.40.10"), + Path("d:/PhysioTwin4D/duke_data/greedy_registrations/results_raw/greedy_80.40.5"), ] # Fixed train/test split: sort patients in ``ref_data_dir`` by filename; diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/3-eval_icon.py b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/3-eval_icon.py index 42da215..715684e 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/3-eval_icon.py +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/3-eval_icon.py @@ -22,7 +22,7 @@ import itk import numpy as np -from physiomotion4d import ( +from physiotwin4d import ( RegisterImagesBase, RegisterImagesGreedy, RegisterImagesGreedyICON, @@ -30,9 +30,9 @@ RegisterTimeSeriesImages, SegmentHeartSimpleware, ) -from physiomotion4d.labelmap_tools import LabelmapTools -from physiomotion4d.landmark_tools import LandmarkTools -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.labelmap_tools import LabelmapTools +from physiotwin4d.landmark_tools import LandmarkTools +from physiotwin4d.transform_tools import TransformTools def _build_registrar( @@ -69,8 +69,8 @@ def _build_registrar( # ## 1. Hard-coded paths and configuration # %% -timepoint_base_dir = Path("d:/PhysioMotion4D/duke_data/gated_nii") -segmentation_base_dir = Path("d:/PhysioMotion4D/duke_data/simple_ascardio") +timepoint_base_dir = Path("d:/PhysioTwin4D/duke_data/gated_nii") +segmentation_base_dir = Path("d:/PhysioTwin4D/duke_data/simple_ascardio") _HERE = Path(__file__).parent output_dir = _HERE / "results_icon_eval" diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/registration_test.py b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/registration_test.py index 0c66ef3..9ec0f30 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/registration_test.py +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/registration_test.py @@ -15,10 +15,10 @@ import itk -from physiomotion4d.register_images_ants import RegisterImagesANTS -from physiomotion4d.register_images_greedy import RegisterImagesGreedy -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.register_images_ants import RegisterImagesANTS +from physiotwin4d.register_images_greedy import RegisterImagesGreedy +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.transform_tools import TransformTools # %% [markdown] # ## 1. Configuration and hard-coded paths @@ -29,7 +29,7 @@ # %% method = "Greedy" # one of: "ANTS", "ICON", "Greedy" -data_dir = Path("d:/PhysioMotion4D/duke_data/gated_nii/pm0003") +data_dir = Path("d:/PhysioTwin4D/duke_data/gated_nii/pm0003") moving_path = data_dir / "pm0003_dupr_135-0094_135_4700_g020_s2.000_n0058_11.nii.gz" fixed_path = data_dir / "pm0003_dupr_135-0094_135_4700_g060_s2.000_n0058_15.nii.gz" diff --git a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/setup.sh b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/setup.sh index b51e9d0..8c61fa7 100644 --- a/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/setup.sh +++ b/experiments/Heart-GatedCT-OptimizedLongitudinalRegistration/setup.sh @@ -33,6 +33,6 @@ if [ -z "$PYTHON" ]; then exit 1 fi -# Install all dependencies (including editable physiomotion4d and uniGradICON) +# Install all dependencies (including editable physiotwin4d and uniGradICON) "$PYTHON" -m pip install uv "$PYTHON" -m uv pip install -e ".[dev,docs,test,cuda13]" diff --git a/experiments/Heart-GatedCT_To_USD/0-download_and_convert_4d_to_3d.py b/experiments/Heart-GatedCT_To_USD/0-download_and_convert_4d_to_3d.py index 33d3514..25f56ca 100644 --- a/experiments/Heart-GatedCT_To_USD/0-download_and_convert_4d_to_3d.py +++ b/experiments/Heart-GatedCT_To_USD/0-download_and_convert_4d_to_3d.py @@ -3,8 +3,8 @@ import shutil from pathlib import Path -from physiomotion4d.convert_image_4d_to_3d import ConvertImage4DTo3D -from physiomotion4d.data_download_tools import DataDownloadTools +from physiotwin4d.convert_image_4d_to_3d import ConvertImage4DTo3D +from physiotwin4d.data_download_tools import DataDownloadTools _HERE = Path(__file__).resolve().parent diff --git a/experiments/Heart-GatedCT_To_USD/1-register_images.py b/experiments/Heart-GatedCT_To_USD/1-register_images.py index 153d175..a665aec 100644 --- a/experiments/Heart-GatedCT_To_USD/1-register_images.py +++ b/experiments/Heart-GatedCT_To_USD/1-register_images.py @@ -4,12 +4,12 @@ import itk -from physiomotion4d.register_images_ants import RegisterImagesANTS -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.register_images_ants import RegisterImagesANTS +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) -from physiomotion4d.test_tools import TestTools -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.test_tools import TestTools +from physiotwin4d.transform_tools import TransformTools # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the diff --git a/experiments/Heart-GatedCT_To_USD/2-generate_segmentation.py b/experiments/Heart-GatedCT_To_USD/2-generate_segmentation.py index a5dbc10..0df8de6 100644 --- a/experiments/Heart-GatedCT_To_USD/2-generate_segmentation.py +++ b/experiments/Heart-GatedCT_To_USD/2-generate_segmentation.py @@ -6,11 +6,11 @@ import numpy as np import pyvista as pv -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the diff --git a/experiments/Heart-GatedCT_To_USD/3-transform_dynamic_and_static_contours.py b/experiments/Heart-GatedCT_To_USD/3-transform_dynamic_and_static_contours.py index 26f34ad..8dcdbf0 100644 --- a/experiments/Heart-GatedCT_To_USD/3-transform_dynamic_and_static_contours.py +++ b/experiments/Heart-GatedCT_To_USD/3-transform_dynamic_and_static_contours.py @@ -5,11 +5,11 @@ import itk import pyvista as pv -from physiomotion4d import ConvertVTKToUSD -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.test_tools import TestTools -from physiomotion4d.usd_anatomy_tools import USDAnatomyTools +from physiotwin4d import ConvertVTKToUSD +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.test_tools import TestTools +from physiotwin4d.usd_anatomy_tools import USDAnatomyTools # Defensive: this script only reads `seg.all_mask_ids` today, but if anyone # ever adds a `seg.segment(...)` call it would trigger the nnUNet diff --git a/experiments/Heart-GatedCT_To_USD/4-merge_dynamic_and_static_usd.py b/experiments/Heart-GatedCT_To_USD/4-merge_dynamic_and_static_usd.py index aa1152c..5276e8e 100644 --- a/experiments/Heart-GatedCT_To_USD/4-merge_dynamic_and_static_usd.py +++ b/experiments/Heart-GatedCT_To_USD/4-merge_dynamic_and_static_usd.py @@ -2,7 +2,7 @@ # %% import os -from physiomotion4d.usd_tools import USDTools +from physiotwin4d.usd_tools import USDTools _HERE = os.path.dirname(os.path.abspath(__file__)) diff --git a/experiments/Heart-Simpleware_Segmentation/README.md b/experiments/Heart-Simpleware_Segmentation/README.md index b15fd59..0601e18 100644 --- a/experiments/Heart-Simpleware_Segmentation/README.md +++ b/experiments/Heart-Simpleware_Segmentation/README.md @@ -1,10 +1,10 @@ # Heart Segmentation using Simpleware Medical -This experiment demonstrates cardiac segmentation using Synopsys Simpleware Medical's ASCardio module integrated with PhysioMotion4D. +This experiment demonstrates cardiac segmentation using Synopsys Simpleware Medical's ASCardio module integrated with PhysioTwin4D. ## Overview -The `SegmentHeartSimpleware` class provides integration between PhysioMotion4D and Synopsys Simpleware Medical for automated heart segmentation. This experiment shows how to: +The `SegmentHeartSimpleware` class provides integration between PhysioTwin4D and Synopsys Simpleware Medical for automated heart segmentation. This experiment shows how to: 1. Load cardiac CT images 2. Segment heart structures using ASCardio @@ -20,7 +20,7 @@ The `SegmentHeartSimpleware` class provides integration between PhysioMotion4D a - Console mode: `ConsoleSimplewareMedical.exe` (command-line version) - ASCardio module license required -- **Python packages** (included in PhysioMotion4D environment): +- **Python packages** (included in PhysioTwin4D environment): - `itk` - `numpy` - `matplotlib` @@ -107,7 +107,7 @@ The script generates: - Input image saved to a temporary NIfTI file - ConsoleSimplewareMedical.exe is launched with `--input-file` (NIfTI) and `--input-value` (output directory) - The Simpleware script runs ASCardio on the loaded image and exports per-structure masks as MHD - - PhysioMotion4D assembles the labelmap from the mask files and returns results + - PhysioTwin4D assembles the labelmap from the mask files and returns results 3. **Postprocessing** (automatic): - Labelmap resampled to original image space @@ -212,13 +212,13 @@ This provides: ## Integration with Other Workflows -This experiment can be combined with other PhysioMotion4D workflows: +This experiment can be combined with other PhysioTwin4D workflows: ### 4D Heart Animation Use segmentation results with `Heart-GatedCT_To_USD` workflow: ```python # After segmentation -from physiomotion4d.workflow_convert_image_to_usd import WorkflowConvertImageToUSD +from physiotwin4d.workflow_convert_image_to_usd import WorkflowConvertImageToUSD workflow = WorkflowConvertImageToUSD() workflow.set_static_labelmap(result["labelmap"]) @@ -228,7 +228,7 @@ workflow.set_static_labelmap(result["labelmap"]) ### Statistical Model Registration Register segmentation with heart model using `Heart-Statistical_Model_To_Patient`: ```python -from physiomotion4d.workflow_fit_statistical_model_to_patient import WorkflowFitStatisticalModelToPatient +from physiotwin4d.workflow_fit_statistical_model_to_patient import WorkflowFitStatisticalModelToPatient workflow = WorkflowFitStatisticalModelToPatient() workflow.set_patient_segmentation(result["labelmap"]) @@ -245,7 +245,7 @@ lv_mask = np.where(labelmap_array == 1, 1, 0) lv_volume_ml = np.sum(lv_mask) * voxel_volume / 1000 # Create mesh for computational modeling -from physiomotion4d.convert_vtk_to_usd import create_mesh_from_mask +from physiotwin4d.convert_vtk_to_usd import create_mesh_from_mask lv_mesh = create_mesh_from_mask(lv_mask) ``` @@ -262,7 +262,7 @@ segmenter.set_target_spacing(2.0) # Use 2mm instead of 1mm 2. **Use region of interest**: ```python # Crop image to heart region before segmentation -from physiomotion4d.image_tools import crop_to_roi +from physiotwin4d.image_tools import crop_to_roi cropped_image = crop_to_roi(input_image, roi_bounds) ``` @@ -270,23 +270,23 @@ cropped_image = crop_to_roi(input_image, roi_bounds) - **Simpleware Medical Documentation**: See Synopsys user manual - **ASCardio Module**: Refer to ASCardio technical documentation -- **PhysioMotion4D**: Main repository documentation +- **PhysioTwin4D**: Main repository documentation ## Citation If using this integration in research, please cite: - Synopsys Simpleware Medical -- PhysioMotion4D framework +- PhysioTwin4D framework - Any relevant papers using ASCardio segmentation ## License -This integration code follows the PhysioMotion4D license. Simpleware Medical and ASCardio are commercial products requiring separate licenses from Synopsys. +This integration code follows the PhysioTwin4D license. Simpleware Medical and ASCardio are commercial products requiring separate licenses from Synopsys. ## Support For issues with: -- **PhysioMotion4D integration**: Submit issue to PhysioMotion4D repository +- **PhysioTwin4D integration**: Submit issue to PhysioTwin4D repository - **Simpleware Medical/ASCardio**: Contact Synopsys support - **This experiment**: Check troubleshooting section above diff --git a/experiments/Heart-Simpleware_Segmentation/simpleware_heart_segmentation.py b/experiments/Heart-Simpleware_Segmentation/simpleware_heart_segmentation.py index c8b5569..a040431 100644 --- a/experiments/Heart-Simpleware_Segmentation/simpleware_heart_segmentation.py +++ b/experiments/Heart-Simpleware_Segmentation/simpleware_heart_segmentation.py @@ -16,7 +16,7 @@ # - Automated heart chamber segmentation (LV, RV, LA, RA) # - Myocardium segmentation # - Major vessel segmentation (aorta, pulmonary artery, coronary arteries) -# - Integration with PhysioMotion4D workflows +# - Integration with PhysioTwin4D workflows # %% [markdown] # ## 1. Setup and Imports @@ -32,9 +32,9 @@ import numpy as np import pyvista as pv -from physiomotion4d.landmark_tools import LandmarkTools -from physiomotion4d.segment_heart_simpleware import SegmentHeartSimpleware -from physiomotion4d.test_tools import TestTools +from physiotwin4d.landmark_tools import LandmarkTools +from physiotwin4d.segment_heart_simpleware import SegmentHeartSimpleware +from physiotwin4d.test_tools import TestTools _HERE = os.path.dirname(os.path.abspath(__file__)) diff --git a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_icp_itk.py b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_icp_itk.py index cb4a563..ee82914 100644 --- a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_icp_itk.py +++ b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_icp_itk.py @@ -23,14 +23,14 @@ import numpy as np import pyvista as pv -# Import from PhysioMotion4D package -from physiomotion4d import ( +# Import from PhysioTwin4D package +from physiotwin4d import ( ContourTools, RegisterModelsICPITK, TransformTools, ) -from physiomotion4d.image_tools import ImageTools -from physiomotion4d.test_tools import TestTools +from physiotwin4d.image_tools import ImageTools +from physiotwin4d.test_tools import TestTools # %% [markdown] # ## Define File Paths diff --git a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_registration_pca.py b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_registration_pca.py index 68d2f8b..b210f66 100644 --- a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_registration_pca.py +++ b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_model_registration_pca.py @@ -25,15 +25,15 @@ import numpy as np import pyvista as pv -# Import from PhysioMotion4D package -from physiomotion4d import ( +# Import from PhysioTwin4D package +from physiotwin4d import ( ContourTools, RegisterModelsICP, RegisterModelsPCA, TransformTools, ) -from physiomotion4d.image_tools import ImageTools -from physiomotion4d.test_tools import TestTools +from physiotwin4d.image_tools import ImageTools +from physiotwin4d.test_tools import TestTools # %% [markdown] # ## Define File Paths diff --git a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.py b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.py index d9ba4a5..5678ecf 100644 --- a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.py +++ b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.py @@ -10,12 +10,12 @@ import itk import pyvista as pv -# Import from PhysioMotion4D package -from physiomotion4d import ( +# Import from PhysioTwin4D package +from physiotwin4d import ( SegmentHeartSimplewareTrimmedBranches, WorkflowFitStatisticalModelToPatient, ) -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # %% [markdown] # ## Define File Paths diff --git a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient.py b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient.py index 3ac6bcd..17bfed3 100644 --- a/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient.py +++ b/experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient.py @@ -12,13 +12,13 @@ import numpy as np import pyvista as pv -# Import from PhysioMotion4D package -from physiomotion4d import ( +# Import from PhysioTwin4D package +from physiotwin4d import ( ContourTools, SegmentChestTotalSegmentator, WorkflowFitStatisticalModelToPatient, ) -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the diff --git a/experiments/Heart-VTKSeries_To_USD/0-download_and_convert_4d_to_3d.py b/experiments/Heart-VTKSeries_To_USD/0-download_and_convert_4d_to_3d.py index 3b8b68f..d129e3b 100644 --- a/experiments/Heart-VTKSeries_To_USD/0-download_and_convert_4d_to_3d.py +++ b/experiments/Heart-VTKSeries_To_USD/0-download_and_convert_4d_to_3d.py @@ -2,8 +2,8 @@ # %% import os -from physiomotion4d.convert_image_4d_to_3d import ConvertImage4DTo3D -from physiomotion4d.data_download_tools import DataDownloadTools +from physiotwin4d.convert_image_4d_to_3d import ConvertImage4DTo3D +from physiotwin4d.data_download_tools import DataDownloadTools _HERE = os.path.dirname(os.path.abspath(__file__)) diff --git a/experiments/Heart-VTKSeries_To_USD/1-heart_vtkseries_to_usd.py b/experiments/Heart-VTKSeries_To_USD/1-heart_vtkseries_to_usd.py index 147a888..7a239b4 100644 --- a/experiments/Heart-VTKSeries_To_USD/1-heart_vtkseries_to_usd.py +++ b/experiments/Heart-VTKSeries_To_USD/1-heart_vtkseries_to_usd.py @@ -5,7 +5,7 @@ import pyvista as pv -from physiomotion4d import ConvertVTKToUSD +from physiotwin4d import ConvertVTKToUSD # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the @@ -20,8 +20,8 @@ # Segment chest from CT images to generate vtk files import itk - from physiomotion4d.contour_tools import ContourTools - from physiomotion4d.segment_chest_total_segmentator_with_contrast import ( + from physiotwin4d.contour_tools import ContourTools + from physiotwin4d.segment_chest_total_segmentator_with_contrast import ( SegmentChestTotalSegmentatorWithContrast, ) diff --git a/experiments/Lung-GatedCT_To_USD/0-register_dirlab_4dct.py b/experiments/Lung-GatedCT_To_USD/0-register_dirlab_4dct.py index fa4a641..ba8c21b 100644 --- a/experiments/Lung-GatedCT_To_USD/0-register_dirlab_4dct.py +++ b/experiments/Lung-GatedCT_To_USD/0-register_dirlab_4dct.py @@ -7,10 +7,10 @@ import numpy as np from data_dirlab_4d_ct import DataDirLab4DCT -from physiomotion4d.image_tools import ImageTools -from physiomotion4d.register_images_icon import RegisterImagesICON -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.image_tools import ImageTools +from physiotwin4d.register_images_icon import RegisterImagesICON +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.transform_tools import TransformTools # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the diff --git a/experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py b/experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py index 252ce0a..fb32134 100644 --- a/experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py +++ b/experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py @@ -5,9 +5,9 @@ import pyvista as pv from data_dirlab_4d_ct import DataDirLab4DCT -from physiomotion4d.contour_tools import ContourTools -from physiomotion4d import ConvertVTKToUSD -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.contour_tools import ContourTools +from physiotwin4d import ConvertVTKToUSD +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator # Defensive: today this script only reads `seg.all_mask_ids`, but if anyone # adds a `seg.segment(...)` call it would trigger the nnUNet diff --git a/experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py b/experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py index dc1dd71..e53087c 100644 --- a/experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py +++ b/experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py @@ -3,8 +3,8 @@ from data_dirlab_4d_ct import DataDirLab4DCT from pxr import Usd -from physiomotion4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator -from physiomotion4d.usd_anatomy_tools import USDAnatomyTools +from physiotwin4d.segment_chest_total_segmentator import SegmentChestTotalSegmentator +from physiotwin4d.usd_anatomy_tools import USDAnatomyTools # Defensive: today this script only instantiates SegmentChestTotalSegmentator # to read its anatomy labels for USDAnatomyTools, but if anyone adds a diff --git a/experiments/Lung-GatedCT_To_USD/Experiment_ArrangeOnStage.py b/experiments/Lung-GatedCT_To_USD/Experiment_ArrangeOnStage.py index b83b00f..b9974d8 100644 --- a/experiments/Lung-GatedCT_To_USD/Experiment_ArrangeOnStage.py +++ b/experiments/Lung-GatedCT_To_USD/Experiment_ArrangeOnStage.py @@ -4,7 +4,7 @@ from data_dirlab_4d_ct import DataDirLab4DCT -from physiomotion4d.usd_tools import USDTools +from physiotwin4d.usd_tools import USDTools # %% os.makedirs("Results_ArrangeOnStage", exist_ok=True) diff --git a/experiments/Lung-GatedCT_To_USD/Experiment_CombineModels.py b/experiments/Lung-GatedCT_To_USD/Experiment_CombineModels.py index b25e4a4..8fafe5b 100644 --- a/experiments/Lung-GatedCT_To_USD/Experiment_CombineModels.py +++ b/experiments/Lung-GatedCT_To_USD/Experiment_CombineModels.py @@ -5,7 +5,7 @@ import itk import pyvista as pv -from physiomotion4d.transform_tools import TransformTools +from physiotwin4d.transform_tools import TransformTools # %% os.makedirs("results_CombineModels", exist_ok=True) diff --git a/experiments/Lung-GatedCT_To_USD/Experiment_SegReg.py b/experiments/Lung-GatedCT_To_USD/Experiment_SegReg.py index f2d5298..cb996c4 100644 --- a/experiments/Lung-GatedCT_To_USD/Experiment_SegReg.py +++ b/experiments/Lung-GatedCT_To_USD/Experiment_SegReg.py @@ -6,8 +6,8 @@ from data_dirlab_4d_ct import DataDirLab4DCT -from physiomotion4d import RegisterImagesICON -from physiomotion4d import SegmentChestTotalSegmentator +from physiotwin4d import RegisterImagesICON +from physiotwin4d import SegmentChestTotalSegmentator # nnUNetv2 (used by TotalSegmentator) spawns a multiprocessing.Pool. On Windows # the spawn start method re-imports this script in each child; without the diff --git a/experiments/Lung-VesselsAirways/0-GenData.py b/experiments/Lung-VesselsAirways/0-GenData.py index 3b6d5e3..d150366 100644 --- a/experiments/Lung-VesselsAirways/0-GenData.py +++ b/experiments/Lung-VesselsAirways/0-GenData.py @@ -7,7 +7,7 @@ import monai import numpy as np import torch -from physiomotion4d.notebook_utils import running_as_test +from physiotwin4d.notebook_utils import running_as_test from scipy.interpolate import UnivariateSpline from torch.utils.data import DataLoader, Dataset diff --git a/experiments/README.md b/experiments/README.md index 398823c..079c109 100644 --- a/experiments/README.md +++ b/experiments/README.md @@ -1,7 +1,7 @@ -# PhysioMotion4D Experiments +# PhysioTwin4D Experiments This directory contains research and design experiments that informed the development -of the PhysioMotion4D library. +of the PhysioTwin4D library. **These are not examples of how to use the library**. @@ -14,9 +14,9 @@ of the PhysioMotion4D library. - Command-line tools and parameter specifications See: -- **CLI Commands**: Run `physiomotion4d-convert-image-to-usd --help`, `physiomotion4d-create-statistical-model --help`, and `physiomotion4d-fit-statistical-model-to-patient --help` -- **CLI Implementation**: `src/physiomotion4d/cli/` for Python API examples -- **Library Classes**: `src/physiomotion4d/` for all workflow and utility classes +- **CLI Commands**: Run `physiotwin4d-convert-image-to-usd --help`, `physiotwin4d-create-statistical-model --help`, and `physiotwin4d-fit-statistical-model-to-patient --help` +- **CLI Implementation**: `src/physiotwin4d/cli/` for Python API examples +- **Library Classes**: `src/physiotwin4d/` for all workflow and utility classes The experiments here serve as **conceptual references** showing the research process and design explorations that can inform adaptation to new digital twin models and tasks. @@ -36,8 +36,8 @@ These experiments demonstrate key digital twin workflows that can be adapted to anatomical regions, imaging modalities, and physiological motion tasks. > **Note:** For production implementations of these workflows, use the CLI commands -> (`physiomotion4d-convert-image-to-usd`, `physiomotion4d-create-statistical-model`, `physiomotion4d-fit-statistical-model-to-patient`) or consult -> the CLI implementation in `src/physiomotion4d/cli/` for proper class usage and parameter specifications. +> (`physiotwin4d-convert-image-to-usd`, `physiotwin4d-create-statistical-model`, `physiotwin4d-fit-statistical-model-to-patient`) or consult +> the CLI implementation in `src/physiotwin4d/cli/` for proper class usage and parameter specifications. ### `Reconstruct4DCT` - High-Resolution 4D Reconstruction @@ -177,7 +177,7 @@ to new anatomical regions, physiological processes, and digital twin application ### General Adaptation Strategy 1. **Study the experiment conceptually** - Understand the workflow stages and data transformations -2. **Consult the CLI implementation** - See `src/physiomotion4d/cli/` to identify production classes and methods that implement similar functionality +2. **Consult the CLI implementation** - See `src/physiotwin4d/cli/` to identify production classes and methods that implement similar functionality 3. **Identify customization points:** - Registration parameters (metrics, transforms, optimization) - Segmentation models (custom training, fine-tuning, label mappings) @@ -189,7 +189,7 @@ to new anatomical regions, physiological processes, and digital twin application ### Key Takeaway These experiments are **starting points for exploration**, not copy-paste solutions. -The **CLI commands and implementations in `src/physiomotion4d/cli/`** are the production-quality +The **CLI commands and implementations in `src/physiotwin4d/cli/`** are the production-quality code you should use and extend for real-world digital twin projects. ## Automated Testing @@ -215,7 +215,7 @@ pytest tests/test_experiments.py::test_experiment_structure -v --run-experiments ### Test Features -- **Test-mode flag** - When run as tests (pytest with `--run-experiments`), the runner sets `PHYSIOMOTION_RUNNING_AS_TEST=1`. Scripts can read this (e.g. via `physiomotion4d.test_tools.TestTools.running_as_test()`) and use reduced parameters so test runs stay fast. See [tests/EXPERIMENT_TESTS_GUIDE.md](../tests/EXPERIMENT_TESTS_GUIDE.md#running-as-test-physiomotion_running_as_test). +- **Test-mode flag** - When run as tests (pytest with `--run-experiments`), the runner sets `PHYSIOTWIN_RUNNING_AS_TEST=1`. Scripts can read this (e.g. via `physiotwin4d.test_tools.TestTools.running_as_test()`) and use reduced parameters so test runs stay fast. See [tests/EXPERIMENT_TESTS_GUIDE.md](../tests/EXPERIMENT_TESTS_GUIDE.md#running-as-test-physiotwin_running_as_test). - **One test per subdirectory** - Each experiment subdirectory gets its own test function - **Alphanumeric ordering** - Scripts execute in alphanumeric order (e.g., `0-`, `1-`, `2-`) - **Long timeouts** - Each script has up to 1 hour execution time, tests have multi-hour timeouts @@ -274,13 +274,13 @@ Each subdirectory represents a different experimental domain: ### For Production Use, Consult: 1. **CLI Commands** ⭐ **PRIMARY RESOURCE** - - `physiomotion4d-convert-image-to-usd` - Complete heart-gated CT workflow - - `physiomotion4d-create-statistical-model` - Create PCA statistical shape model from sample meshes - - `physiomotion4d-fit-statistical-model-to-patient` - Model-to-patient registration + - `physiotwin4d-convert-image-to-usd` - Complete heart-gated CT workflow + - `physiotwin4d-create-statistical-model` - Create PCA statistical shape model from sample meshes + - `physiotwin4d-fit-statistical-model-to-patient` - Model-to-patient registration - Run with `--help` for all options and parameter specifications - Tested on diverse datasets -2. **CLI Implementation in `src/physiomotion4d/cli/`** +2. **CLI Implementation in `src/physiotwin4d/cli/`** - Production-ready workflow code - Proper class usage patterns and parameter specifications - Complete error handling and validation @@ -310,7 +310,7 @@ Each subdirectory represents a different experimental domain: - Paths and parameters are often hardcoded for specific datasets - Performance may not be optimized -**INSTEAD:** Use the CLI commands or the production implementations in `src/physiomotion4d/cli/` and extend them for your needs. +**INSTEAD:** Use the CLI commands or the production implementations in `src/physiotwin4d/cli/` and extend them for your needs. ## Development History @@ -336,10 +336,10 @@ The typical evolution path was: When exploring new digital twin applications, you can follow a similar path: - Start by understanding relevant experiments here as conceptual references -- Examine CLI implementations in `src/physiomotion4d/cli/` for proper library usage -- Use CLI commands (`physiomotion4d-convert-image-to-usd`, `physiomotion4d-create-statistical-model`, `physiomotion4d-fit-statistical-model-to-patient`) as starting points +- Examine CLI implementations in `src/physiotwin4d/cli/` for proper library usage +- Use CLI commands (`physiotwin4d-convert-image-to-usd`, `physiotwin4d-create-statistical-model`, `physiotwin4d-fit-statistical-model-to-patient`) as starting points - Extend and adapt production code with your domain-specific requirements - Contribute back improvements and new capabilities to the community -**Remember:** The CLI commands and their implementations in `src/physiomotion4d/cli/` are your -source of truth for how to properly use PhysioMotion4D classes, workflows, and capabilities in production environments. +**Remember:** The CLI commands and their implementations in `src/physiotwin4d/cli/` are your +source of truth for how to properly use PhysioTwin4D classes, workflows, and capabilities in production environments. diff --git a/experiments/Reconstruct4DCT/reconstruct_4d_ct.py b/experiments/Reconstruct4DCT/reconstruct_4d_ct.py index a2e6a39..c9b1439 100644 --- a/experiments/Reconstruct4DCT/reconstruct_4d_ct.py +++ b/experiments/Reconstruct4DCT/reconstruct_4d_ct.py @@ -5,7 +5,7 @@ import itk import numpy as np -from physiomotion4d import RegisterImagesGreedy, TestTools, TransformTools +from physiotwin4d import RegisterImagesGreedy, TestTools, TransformTools _HERE = os.path.dirname(os.path.abspath(__file__)) diff --git a/experiments/Reconstruct4DCT/reconstruct_4d_ct_class.py b/experiments/Reconstruct4DCT/reconstruct_4d_ct_class.py index cde6e37..ad1b320 100644 --- a/experiments/Reconstruct4DCT/reconstruct_4d_ct_class.py +++ b/experiments/Reconstruct4DCT/reconstruct_4d_ct_class.py @@ -17,7 +17,7 @@ import itk import numpy as np -from physiomotion4d import ( +from physiotwin4d import ( RegisterImagesBase, RegisterImagesGreedy, RegisterImagesGreedyICON, @@ -25,7 +25,7 @@ RegisterTimeSeriesImages, TransformTools, ) -from physiomotion4d.test_tools import TestTools +from physiotwin4d.test_tools import TestTools _HERE = os.path.dirname(os.path.abspath(__file__)) diff --git a/statistics.md b/statistics.md index db3ead9..971adc7 100644 --- a/statistics.md +++ b/statistics.md @@ -1,4 +1,4 @@ -# PhysioMotion4D - Software Development Statistics +# PhysioTwin4D - Software Development Statistics **Report Generated:** May 13, 2026 **Project Version:** 2026.05.07 @@ -8,7 +8,7 @@ ## Executive Summary -PhysioMotion4D is a medical imaging package for generating anatomic models in +PhysioTwin4D is a medical imaging package for generating anatomic models in NVIDIA Omniverse with physiological motion derived from 4D medical images. This report summarizes development effort, code quality, and project maturity. @@ -77,7 +77,7 @@ percent-cell markers so the same file can be executed end-to-end with ### Domain Complexity -PhysioMotion4D operates across several technically demanding domains: +PhysioTwin4D operates across several technically demanding domains: | Domain | Complexity Level | Key Technologies | | ------------------------ | ---------------- | -------------------------------------- | @@ -91,7 +91,7 @@ PhysioMotion4D operates across several technically demanding domains: ### Architectural Sophistication - Class hierarchy depth: 3-4 levels (well-structured inheritance from - `PhysioMotion4DBase`) + `PhysioTwin4DBase`) - Module coupling: medium (clear separation between segmentation, registration, USD conversion, and workflow layers) - Public API surface documented in `docs/API_MAP.md` @@ -161,7 +161,7 @@ PhysioMotion4D operates across several technically demanding domains: ### Documentation Highlights - Quickstart, tutorials, examples, and architecture under `docs/` -- Per-subpackage READMEs (e.g. `src/physiomotion4d/vtk_to_usd/CLAUDE.md`) +- Per-subpackage READMEs (e.g. `src/physiotwin4d/vtk_to_usd/CLAUDE.md`) - Contribution and testing guides - FAQ and troubleshooting sections in test docs @@ -169,7 +169,7 @@ PhysioMotion4D operates across several technically demanding domains: ## Summary -PhysioMotion4D is a beta-quality medical imaging toolkit that bridges 4D CT +PhysioTwin4D is a beta-quality medical imaging toolkit that bridges 4D CT data, AI segmentation and registration, VTK geometry, and OpenUSD output for NVIDIA Omniverse. It is built on top of established medical imaging and 3D graphics libraries with a small, focused public API and a percent-cell-script diff --git a/utils/ai_agent_github_reviews.py b/utils/ai_agent_github_reviews.py index 8252bff..7e760f8 100644 --- a/utils/ai_agent_github_reviews.py +++ b/utils/ai_agent_github_reviews.py @@ -571,7 +571,7 @@ def _agent_guidance_files(agent: str, repo_root: Path) -> list[str]: def _agent_scoped_guidance_files(agent: str, repo_root: Path) -> list[str]: """Return existing scoped guidance files relevant to the selected AI agent.""" agent_file = _agent_specific_guidance_file(agent) - scoped_file = Path("src") / "physiomotion4d" / "vtk_to_usd" / agent_file + scoped_file = Path("src") / "physiotwin4d" / "vtk_to_usd" / agent_file if (repo_root / scoped_file).exists(): return [scoped_file.as_posix()] return [] @@ -649,10 +649,10 @@ def build_prompt( - Introduces `X | None` instead of `Optional[X]` (ruff UP007 is suppressed) - Adds backward-compat shims, re-exports, or removed-symbol stubs - Adds error handling for internal states that cannot happen - - In classes that inherit from `PhysioMotion4DBase`, uses `print()` instead + - In classes that inherit from `PhysioTwin4DBase`, uses `print()` instead of `self.log_info()` / `self.log_debug()` - New runtime workflow / segmentation / registration class does not inherit - from `PhysioMotion4DBase`; helper/data/container classes need not + from `PhysioTwin4DBase`; helper/data/container classes need not - Adds features or abstractions beyond what was requested - Calls `vtk_to_usd` internals from outside `convert_vtk_to_usd.py` - Applies coordinate conversion (LPS->USD Y-up) more than once, or diff --git a/utils/generate_api_map.py b/utils/generate_api_map.py index 52b009c..2b83380 100644 --- a/utils/generate_api_map.py +++ b/utils/generate_api_map.py @@ -10,7 +10,7 @@ python utils/generate_api_map.py [root_dir] If root_dir is omitted, uses the parent of the directory containing this -script (i.e. the physiomotion4d project root). +script (i.e. the physiotwin4d project root). """ from __future__ import annotations