ENH: Add NV-Segment-CTMR segmentation backend - #104
Conversation
Add SegmentNVSegmentCTMRI, a VISTA3D-derived segmenter wrapping NVIDIA's
NV-Segment-CTMR model (345 classes across CT_BODY, MRI_BODY, MRI_BRAIN).
Weights are pulled from HuggingFace on first use; the OneWay Non-Commercial
license is logged at WARNING on first call.
- SegmentAnatomyBase gains labelmap_dtype (default np.uint8) and
_finalize_other_group(id_range) so backends whose class indices exceed 255
can emit uint16 labelmaps. NV-Segment-CTMR uses the model's published
indices verbatim (up to 345), so it sets np.uint16.
- Register the backend in physiotwin4d.__init__, the CLI factory
("NVSegmentCTMR"), and a session-scoped conftest fixture.
- USDAnatomyTools: add render params for the new brain_parcellation group --
shared grey-matter and CSF dicts plus overrides for white matter, WMH,
ventricles, pallidum, brain stem, and cerebellar cortex. Several keys exist
only to outrank shorter substring matches (e.g. "lateral_ventricle" vs the
heart's "ventricle_left").
- Docs: API page for the new segmenter, plus architecture/FAQ/workflow updates.
- Experiments: add Lung-GatedCT_To_USD_NV variant of the DIRLAB pipeline
(4DCT registration, model building, painting).
- Tutorials: add tutorial_04_lung_create_statistical_model.
Breaking API changes:
- ContourTools.save_combined_surface(surfaces, output_dir, prefix) ->
save_combined_surfaces(surfaces, output_filename).
- WorkflowCreateStatisticalModel.run_workflow() -> process(), matching the
other workflows. Default pca_number_of_components 15 -> 7.
- WorkflowConvertImageToVTK.ANATOMY_GROUPS -> anatomy_groups (instance
attribute, not a constant).
- ContourTools.extract_contours() exposes smoothing_iterations and
smoothing_scale, and no longer applies a hard-coded Taubin pass afterward.
- Module-level _extract_surface() folded into ContourTools.extract_surface().
|
Warning Review limit reached
Next review available in: 22 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
WalkthroughAdded the NV-Segment-CTMR backend for CT and MRI segmentation, including taxonomy and rendering support. Updated contour and workflow APIs, added DirLab processing scripts, aligned tutorials and documentation, and added backend tests. ChangesNV-Segment-CTMR integration
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Caller
participant SegmentNVSegmentCTMRI
participant HuggingFace
participant VISTA3D
Caller->>SegmentNVSegmentCTMRI: select modality and request segmentation
SegmentNVSegmentCTMRI->>HuggingFace: download or reuse model bundle
SegmentNVSegmentCTMRI->>VISTA3D: run CUDA inference
VISTA3D-->>SegmentNVSegmentCTMRI: return labelmap
SegmentNVSegmentCTMRI-->>Caller: return uint16 labelmap
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds a new NVIDIA NV-Segment-CTMR segmentation backend (SegmentNVSegmentCTMRI) to PhysioTwin4D, including taxonomy/group registration, CLI wiring, rendering defaults for a new brain_parcellation group, updated workflow/tutorial call sites for breaking API renames, and tests/docs/experiments to support the new backend.
Changes:
- Introduces
SegmentNVSegmentCTMRI(HuggingFace snapshot download + VISTA3D pipeline) and registers it across__init__, CLI factories, and test fixtures. - Extends segmentation + surface tooling APIs to support larger label index spaces (
labelmap_dtype, wider “other” sweep) and renamessave_combined_surface→save_combined_surfaces. - Adds brain-parcellation USD render defaults and updates docs/tutorials/experiments accordingly.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tutorials/tutorial_04_lung_create_statistical_model.py | New lung PCA statistical model tutorial (DirLab-based). |
| tutorials/tutorial_04_heart_create_statistical_model.py | Updates workflow call to process(). |
| tutorials/tutorial_02_lung_ct_to_vtk.py | Updates combined-surface save API usage. |
| tutorials/tutorial_02_heart_ct_to_vtk.py | Updates combined-surface save API usage. |
| tutorials/tutorial_01_lung_gated_ct_to_usd.py | Adjusts DirLab path selection and playback FPS. |
| tests/test_segment_nv_segment_ct_mri.py | Adds configuration + GPU/slow end-to-end tests for NV-Segment-CTMR. |
| tests/conftest.py | Registers a session-scoped SegmentNVSegmentCTMRI fixture. |
| src/physiotwin4d/workflow_create_statistical_model.py | Renames entrypoint to process(), adjusts defaults, uses ContourTools.extract_surface. |
| src/physiotwin4d/workflow_convert_image_to_vtk.py | Replaces ANATOMY_GROUPS constant with instance anatomy_groups and updates validation/docs. |
| src/physiotwin4d/usd_anatomy_tools.py | Adds brain_parcellation defaults + tissue overrides for USD materials. |
| src/physiotwin4d/segment_nv_segment_ct_mri.py | New NV-Segment-CTMR backend implementation. |
| src/physiotwin4d/segment_anatomy_base.py | Adds labelmap_dtype and widens _finalize_other_group() sweep; casts labelmap to configured dtype. |
| src/physiotwin4d/contour_tools.py | Exposes contour smoothing params, adds extract_surface, renames combined-surface saver. |
| src/physiotwin4d/cli/create_statistical_model.py | Updates workflow call to process(). |
| src/physiotwin4d/cli/convert_image_to_vtk.py | Updates anatomy-group choices var and combined-surface save path behavior. |
| src/physiotwin4d/cli/_method_factories.py | Registers NVSegmentCTMR backend name and factory mapping. |
| src/physiotwin4d/init.py | Exports SegmentNVSegmentCTMRI. |
| pyproject.toml | Updates mypy module ignore list for NV bundle modules. |
| experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py | Uses Path for results directory. |
| experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py | Uses Path for results directory. |
| experiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.py | New NV-backed DIRLAB registration experiment script. |
| experiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.py | New NV-backed DIRLAB model-building experiment script. |
| experiments/Lung-GatedCT_To_USD_NV/2-paint_dirlab_models.py | New NV-backed USD painting experiment script. |
| docs/tutorials.rst | Updates run_workflow() → process() usage. |
| docs/faq.rst | Adds NV-Segment-CTMR option + license caveat. |
| docs/architecture.rst | Adds the new segmenter to architecture flow/docs. |
| docs/api/workflows.rst | Updates combined-surface save API usage in docs. |
| docs/api/segmentation/nv_segment_ct_mri.rst | New API documentation page for NV-Segment-CTMR. |
| docs/api/segmentation/index.rst | Adds NV-Segment-CTMR to segmentation overview. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/physiotwin4d/contour_tools.py (1)
35-58: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDocument the new smoothing parameters.
Lines 37-38 add public parameters, but the docstring does not describe them. Add
smoothing_iterationsandsmoothing_scaletoArgs, including their effect and valid values.As per coding guidelines, "
**/*.{py,md,rst}: Update docstrings for every changed public method."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/physiotwin4d/contour_tools.py` around lines 35 - 58, Update the extract_contours docstring’s Args section to document smoothing_iterations and smoothing_scale, including how each controls contour smoothing and their valid values. Keep the existing parameter descriptions unchanged.Source: Coding guidelines
src/physiotwin4d/workflow_create_statistical_model.py (1)
48-57: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd the constructor return annotation.
WorkflowCreateStatisticalModel.__init__needs-> Nonefor strict mypy-compatible type hints.As per coding guidelines, "
**/*.py: Use ... full type hints compatible with strict mypy."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/physiotwin4d/workflow_create_statistical_model.py` around lines 48 - 57, Add a -> None return annotation to the WorkflowCreateStatisticalModel.__init__ method signature, preserving all existing parameters and defaults.Source: Coding guidelines
🧹 Nitpick comments (6)
src/physiotwin4d/segment_nv_segment_ct_mri.py (1)
629-633: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winCheck CUDA availability before you build the pipeline.
The device is hard-coded to
cuda:0. On a CPU-only hosttorchraises a low-level assertion that does not name the cause. Raise an explicit error instead.Proposed change
+ if not torch.cuda.is_available(): + raise RuntimeError( + "NV-Segment-CTMR requires a CUDA device; none is available." + ) pipeline = VISTA3DPipeline(model, device=torch.device("cuda:0"))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/physiotwin4d/segment_nv_segment_ct_mri.py` around lines 629 - 633, In the pipeline setup around VISTA3DPipeline, check torch.cuda availability before constructing the pipeline with cuda:0; if CUDA is unavailable, raise a clear explicit error, and preserve the existing GPU pipeline invocation when it is available.tests/test_segment_nv_segment_ct_mri.py (2)
184-189: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftCompare the produced labelmap against a baseline.
The test writes the labelmap but never validates it against a stored reference. Use
TestToolsfromsrc/physiotwin4d/test_tools.pywith a baseline undertests/baselines/.As per path instructions: "When a test produces an image or surface, compare it against a baseline using utilities such as
TestToolsfromsrc/physiotwin4d/test_tools.py."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_segment_nv_segment_ct_mri.py` around lines 184 - 189, Update the labelmap test around the output write in the segmentation flow to compare the produced image against a stored baseline under tests/baselines/. Use the existing TestTools utilities from src/physiotwin4d/test_tools.py, preserving the current output generation while asserting the written labelmap matches its corresponding baseline.Source: Path instructions
143-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winState the image shape and axis order in the docstring.
The docstring does not describe the input volume. Add the shape and axis order, for example
shape (X, Y, Z, T) = (..., ..., ..., 1), LPS world frame.As per path instructions: "State image shape and axis order in every test docstring, such as
shape (X, Y, Z, T) = (64, 64, 32, 1), LPS world frame."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_segment_nv_segment_ct_mri.py` around lines 143 - 164, Update the docstring of test_segment_single_image to state the input image shape and axis order, using the required “shape (X, Y, Z, T) = (..., ..., ..., 1), LPS world frame” format and the test’s actual dimensions.Source: Path instructions
src/physiotwin4d/segment_anatomy_base.py (1)
47-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider a narrower type for
labelmap_dtype.
typeaccepts any class, so strict mypy cannot rejectself.labelmap_dtype = str.type[np.integer]documents and enforces the intended contract.Proposed change
- self.labelmap_dtype: type = np.uint8 + self.labelmap_dtype: type[np.integer] = np.uint8Also applies to: 75-75
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/physiotwin4d/segment_anatomy_base.py` around lines 47 - 50, Update the labelmap_dtype annotation in the segment anatomy base class documentation and corresponding declaration to use type[np.integer] instead of unrestricted type. Preserve the existing np.uint8 default and subclass overrides such as SegmentNVSegmentCTMRI.experiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.py (1)
58-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueKeep the f-string lines at or below 88 characters.
Lines 60, 258, 264, 270, and 276 exceed the limit. Build the file name in a local variable before the call.
As per coding guidelines: "keep lines at or below 88 characters".
Also applies to: 256-260
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@experiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.py` around lines 58 - 62, In the relevant itk.imwrite calls in the registration script, including the blocks around the mask and image outputs, assign each long f-string path to a local filename variable first, then pass that variable to itk.imwrite. Keep every resulting source line at or below 88 characters and preserve the existing filenames and output behavior.Source: Coding guidelines
experiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.py (1)
26-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd type hints to both helper functions.
make_dirlab_modelshas no annotations.transform_contours_listhas no return annotation, and itsoutput_diris annotatedstrwhile line 81 passes thePathcreated at line 23.Proposed change
def transform_contours_list( - contours: pv.PolyData, case_name: str, mask_name: str, output_dir: str - ): + contours: pv.PolyData, case_name: str, mask_name: str, output_dir: Path + ) -> list[pv.PolyData]:def make_dirlab_models( - output_dir, - label, - case_name, - base_timepoint, - all_labelmap_arr, - all_mask_ids, - con_tools, - seg, - ): + output_dir: Path, + label: str, + case_name: str, + base_timepoint: int, + all_labelmap_arr: np.ndarray, + all_mask_ids: dict[int, str], + con_tools: ContourTools, + seg: SegmentNVSegmentCTMRI, + ) -> None:As per coding guidelines: "use full type hints compatible with strict mypy".
Also applies to: 47-56
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@experiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.py` around lines 26 - 28, Update both helper functions, make_dirlab_models and transform_contours_list, with complete strict-mypy-compatible annotations: annotate make_dirlab_models’ parameters and return type, add transform_contours_list’s return type, and change output_dir to match the pathlib.Path value passed by the caller. Ensure all inferred input and output types are explicitly represented without altering behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@experiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.py`:
- Around line 126-144: Update the fixed-image mask construction around
fixed_image_dynamic_anatomy_mask and fixed_image_static_anatomy_mask so every
registration mask is binary: threshold each source label array to
foreground/background before creating the ITK image, and combine static-anatomy
components as a binary union rather than adding label IDs. Apply the same
binarization and union logic to the corresponding moving-image mask block.
- Around line 39-48: Update the register_image function’s fixed_mask and
moving_mask annotations to Optional[itk.image], matching the existing None call
sites and moving_mask null check while following the project’s strict-mypy
typing convention.
In `@src/physiotwin4d/cli/create_statistical_model.py`:
- Line 155: Set the CLI parser’s pca_components default and help text to 7 so
the value passed by the create statistical model workflow remains consistent;
update the constructor documentation in
src/physiotwin4d/workflow_create_statistical_model.py lines 52-63 to document
the default as 7 while keeping its constructor default unchanged.
In `@src/physiotwin4d/segment_nv_segment_ct_mri.py`:
- Around line 556-566: Update the snapshot_download calls in the model
snapshot-loading flow, including the path around the _snapshot_dir assignment,
to pass an explicit pinned Hugging Face revision (commit SHA or audited tag) via
the supported revision parameter. Use the same pin for both affected call sites
and preserve the existing repository, cache, and allow_patterns behavior.
- Around line 604-621: Cache the loaded VISTA3DModel instance on the
segmentation class alongside _snapshot_dir, and update segmentation_method to
reuse that cached model instead of constructing VISTA3DModel and calling
torch.load on every invocation. Initialize or populate the cache once, then
preserve the existing inference behavior for subsequent segment calls.
In `@src/physiotwin4d/workflow_convert_image_to_vtk.py`:
- Line 23: Update the ContourTools.save_combined_surfaces call to access the
surfaces key with double quotes, changing result['surfaces'] to
result["surfaces"] while preserving the existing behavior.
In `@tutorials/tutorial_04_lung_create_statistical_model.py`:
- Around line 9-12: Update the module documentation’s “Data Required” section to
name the DirLab-4DCT dataset used by the tutorial’s data-loading code, and
replace the incorrect KCL-Heart-Model paths with the supported test-data
location if applicable. Keep the documentation aligned with the dataset path
referenced by the tutorial.
- Around line 83-87: Update the itk.imwrite call for sample_labelmap in the
labelmap generation flow to enable compressed persistence by passing
compression=True, while preserving the existing image and output path arguments.
- Around line 71-90: Update the fresh-output branch in the loop over
sample_image_files to assign sample_surface after saving the generated surfaces,
before sample_surfaces.append(sample_surface). Keep the existing pv.read path
for already-created surface files and ensure both branches initialize
sample_surface.
---
Outside diff comments:
In `@src/physiotwin4d/contour_tools.py`:
- Around line 35-58: Update the extract_contours docstring’s Args section to
document smoothing_iterations and smoothing_scale, including how each controls
contour smoothing and their valid values. Keep the existing parameter
descriptions unchanged.
In `@src/physiotwin4d/workflow_create_statistical_model.py`:
- Around line 48-57: Add a -> None return annotation to the
WorkflowCreateStatisticalModel.__init__ method signature, preserving all
existing parameters and defaults.
---
Nitpick comments:
In `@experiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.py`:
- Around line 58-62: In the relevant itk.imwrite calls in the registration
script, including the blocks around the mask and image outputs, assign each long
f-string path to a local filename variable first, then pass that variable to
itk.imwrite. Keep every resulting source line at or below 88 characters and
preserve the existing filenames and output behavior.
In `@experiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.py`:
- Around line 26-28: Update both helper functions, make_dirlab_models and
transform_contours_list, with complete strict-mypy-compatible annotations:
annotate make_dirlab_models’ parameters and return type, add
transform_contours_list’s return type, and change output_dir to match the
pathlib.Path value passed by the caller. Ensure all inferred input and output
types are explicitly represented without altering behavior.
In `@src/physiotwin4d/segment_anatomy_base.py`:
- Around line 47-50: Update the labelmap_dtype annotation in the segment anatomy
base class documentation and corresponding declaration to use type[np.integer]
instead of unrestricted type. Preserve the existing np.uint8 default and
subclass overrides such as SegmentNVSegmentCTMRI.
In `@src/physiotwin4d/segment_nv_segment_ct_mri.py`:
- Around line 629-633: In the pipeline setup around VISTA3DPipeline, check
torch.cuda availability before constructing the pipeline with cuda:0; if CUDA is
unavailable, raise a clear explicit error, and preserve the existing GPU
pipeline invocation when it is available.
In `@tests/test_segment_nv_segment_ct_mri.py`:
- Around line 184-189: Update the labelmap test around the output write in the
segmentation flow to compare the produced image against a stored baseline under
tests/baselines/. Use the existing TestTools utilities from
src/physiotwin4d/test_tools.py, preserving the current output generation while
asserting the written labelmap matches its corresponding baseline.
- Around line 143-164: Update the docstring of test_segment_single_image to
state the input image shape and axis order, using the required “shape (X, Y, Z,
T) = (..., ..., ..., 1), LPS world frame” format and the test’s actual
dimensions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 26e974fa-8d61-4b75-a62a-e4d1b82dae01
📒 Files selected for processing (29)
docs/api/segmentation/index.rstdocs/api/segmentation/nv_segment_ct_mri.rstdocs/api/workflows.rstdocs/architecture.rstdocs/faq.rstdocs/tutorials.rstexperiments/Lung-GatedCT_To_USD/1-make_dirlab_models.pyexperiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.pyexperiments/Lung-GatedCT_To_USD_NV/0-register_dirlab_4dct.pyexperiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.pyexperiments/Lung-GatedCT_To_USD_NV/2-paint_dirlab_models.pypyproject.tomlsrc/physiotwin4d/__init__.pysrc/physiotwin4d/cli/_method_factories.pysrc/physiotwin4d/cli/convert_image_to_vtk.pysrc/physiotwin4d/cli/create_statistical_model.pysrc/physiotwin4d/contour_tools.pysrc/physiotwin4d/segment_anatomy_base.pysrc/physiotwin4d/segment_nv_segment_ct_mri.pysrc/physiotwin4d/usd_anatomy_tools.pysrc/physiotwin4d/workflow_convert_image_to_vtk.pysrc/physiotwin4d/workflow_create_statistical_model.pytests/conftest.pytests/test_segment_nv_segment_ct_mri.pytutorials/tutorial_01_lung_gated_ct_to_usd.pytutorials/tutorial_02_heart_ct_to_vtk.pytutorials/tutorial_02_lung_ct_to_vtk.pytutorials/tutorial_04_heart_create_statistical_model.pytutorials/tutorial_04_lung_create_statistical_model.py
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #104 +/- ##
==========================================
+ Coverage 35.40% 35.61% +0.21%
==========================================
Files 63 64 +1
Lines 8203 8277 +74
==========================================
+ Hits 2904 2948 +44
- Misses 5299 5329 +30
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated no new comments.
Suppressed comments (7)
src/physiotwin4d/segment_nv_segment_ct_mri.py:601
- _ensure_pipeline mutates global sys.path by inserting the downloaded Hugging Face snapshot directory, but it never removes it. This can cause surprising import shadowing later in the process (especially since the snapshot contains top-level module names). Prefer adding the path only for the duration of the local imports, then removing it.
# The bundle ships hugging_face_pipeline / vista3d_pipeline as
# top-level modules inside the snapshot rather than as an installed
# package, so the snapshot directory has to be importable.
if snapshot_dir not in sys.path:
sys.path.insert(0, snapshot_dir)
tutorials/tutorial_04_lung_create_statistical_model.py:13
- The tutorial header claims a "Test data" path under data/test/DirLab-4DCT, but the repository does not ship a DirLab-4DCT test subset (only data/test/README.md and .gitignore). This is likely to confuse readers; suggest removing the test-data line or clarifying that there is no bundled test subset.
Full data: ``data/DirLab-4DCT/Case*T70.mha``
Test data: ``data/test/DirLab-4DCT/Case*T70.mha``
DirLab-4DCT is not auto-downloaded — see ``data/DirLab-4DCT/README.md``.
experiments/Lung-GatedCT_To_USD/1-make_dirlab_models.py:23
- output_dir was changed to a Path, but the rest of this script builds paths via f"{output_dir}/...". On Windows this can produce mixed separators like "C:\...\results/Case...". Either keep output_dir as a str here, or switch the downstream path building to Path operations.
output_dir = Path(__file__).parent / "results"
experiments/Lung-GatedCT_To_USD/2-paint_dirlab_models.py:20
- output_dir was changed to a Path, but this script still uses f"{output_dir}/..." to build filenames. On Windows this can produce mixed separators (backslashes plus "/"), which can break downstream tools. Either keep output_dir as a str or convert the f-strings to Path joins.
output_dir = Path(__file__).parent / "results"
experiments/Lung-GatedCT_To_USD_NV/1-make_dirlab_models.py:23
- output_dir is a Path, but downstream filenames are constructed via f"{output_dir}/...". On Windows this can produce mixed separators like "C:\...\results/Case...". Either keep output_dir as a str or use Path / joins throughout.
output_dir = Path(__file__).parent / "results"
experiments/Lung-GatedCT_To_USD_NV/2-paint_dirlab_models.py:20
- output_dir is a Path, but the script constructs USD paths via f"{output_dir}/...". On Windows this can yield mixed separators (backslashes plus "/"), which can break consumers. Prefer Path joining (output_dir / filename) or keep output_dir as a str.
output_dir = Path(__file__).parent / "results"
src/physiotwin4d/contour_tools.py:39
- extract_contours() now exposes smoothing_iterations and smoothing_scale, but the docstring still documents only labelmap_image. Please document the new parameters so callers know what they control and their defaults.
def extract_contours(
labelmap_image: itk.image,
smoothing_iterations: int = 10,
smoothing_scale: float = 1.0,
) -> pv.PolyData:
Add SegmentNVSegmentCTMRI, a VISTA3D-derived segmenter wrapping NVIDIA's NV-Segment-CTMR model (345 classes across CT_BODY, MRI_BODY, MRI_BRAIN). Weights are pulled from HuggingFace on first use; the OneWay Non-Commercial license is logged at WARNING on first call.
Breaking API changes:
Summary by CodeRabbit
New Features
Enhancements
Documentation
Bug Fixes