Skip to content

ENH: Provide consistent colormap use for Alterra and TPV25 valves#33

Merged
aylward merged 3 commits intoProject-MONAI:mainfrom
aylward:ColormapValves
Mar 28, 2026
Merged

ENH: Provide consistent colormap use for Alterra and TPV25 valves#33
aylward merged 3 commits intoProject-MONAI:mainfrom
aylward:ColormapValves

Conversation

@aylward
Copy link
Copy Markdown
Collaborator

@aylward aylward commented Mar 1, 2026

Set colormap, intensity range, and use of sigmoid transfer function when mapping stress measure from valve simulations to colormaps when generating USD files.

Summary by CodeRabbit

  • New Features

    • Added CT→VTK conversion workflow and a CLI to run it.
    • New exportable workflow included in the package API.
    • Added anatomy color lookup, landmark support, and configurable registration weights.
    • New notebooks for model-to-patient, conversion, and reconstruction workflows.
  • Documentation

    • New repository guidance document with usage, workflow overview, and development commands.
  • Chores

    • Quick-run/test mode and standardized output naming; streamlined conversion and colorization defaults.
  • Misc

    • Updated .gitignore to ignore .mha files.

Copilot AI review requested due to automatic review settings March 1, 2026 20:05
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 1, 2026

Walkthrough

Added a CT→VTK conversion workflow and CLI, extended statistical-model-to-patient workflow with optional CT→VTK conversion and labelmap outputs, reworked multiple VTK→USD notebooks to add quick_run/test mode and simplified colormap application, and introduced several API additions (USD color accessor, ICON weights, landmarks support) plus assorted notebooks and docs.

Changes

Cohort / File(s) Summary
VTK→USD notebooks
experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.ipynb, experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb, experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb
Introduced quick_run test mode, renamed/reorganized path vars, unified conversion flows, added ConversionSettings/MaterialData, subsampled time-series for tests, and replaced legacy colorization with primvar-driven apply_colormap_from_primvar. Heart notebook also adds per-part and whole-heart combined exports.
New CT→VTK workflow & API
src/physiomotion4d/workflow_convert_ct_to_vtk.py, src/physiomotion4d/__init__.py
Added WorkflowConvertCTToVTK implementing segmentation backend selection, per-anatomy surface/mesh extraction, field_data/cell_data annotation, and file-saving helpers; exported class in package __all__.
Workflow integrations
src/physiomotion4d/workflow_fit_statistical_model_to_patient.py
WorkflowFitStatisticalModelToPatient now optionally runs CT→VTK conversion when patient_models not supplied, adds segmentation_method param, returns registered_template_labelmap, and adjusts mask dilation defaults.
CLI
src/physiomotion4d/cli/convert_ct_to_vtk.py, pyproject.toml
Added CLI entrypoint physiomotion4d-convert-ct-to-vtk with argument validation, ITK image loading, runs WorkflowConvertCTToVTK, and saves combined or per-group VTK/VTU outputs; pyproject adds script entry and cupy-cuda13x bump and [tool.uv].
Color / anatomy utilities
src/physiomotion4d/usd_anatomy_tools.py
Added USDAnatomyTools.get_anatomy_diffuse_color(anatomy_type) accessor returning normalized RGB and raising on unknown types.
Registration / weights
src/physiomotion4d/register_images_icon.py
Added weights_path attribute and set_weights_path() to inject custom uniGradICON weights; network init uses provided weights path.
Segmentation / landmarks
src/physiomotion4d/segment_heart_simpleware.py, src/physiomotion4d/simpleware_medical/SimplewareScript_heart_segmentation.py
Simpleware integration now exports landmarks to landmarks.csv; SegmentHeartSimpleware stores parsed self.landmarks and exposes get_landmarks().
Contour handling
src/physiomotion4d/contour_tools.py
Robustified face-index extraction for PyVista PolyData by computing points-per-face dynamically before slicing out indices.
Notebooks & experiments
experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.ipynb, experiments/Reconstruct4DCT/reconstruct_4d_ct_class.ipynb
Added new model-to-patient notebook that runs statistical registration and saves outputs; reconstruct notebook reduced registration methods to ants only.
Docs & misc
CLAUDE.md, data/DirLab-4DCT/.gitignore
Added repository guidance CLAUDE.md; updated .gitignore to ignore *.mha.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User as Notebook/CLI
participant Workflow as WorkflowConvertCTToVTK
participant Segmenter as SegmentationBackend
participant Contour as ContourTools
participant Saver as FileSystem

User->>Workflow: run_workflow(input_image, anatomy_groups, ...)
Workflow->>Segmenter: instantiate & run segmentation (lazy backend)
Segmenter-->>Workflow: labelmap + segmentation masks
Workflow->>Contour: extract_contours / build meshes (per group)
Contour-->>Workflow: pv.PolyData / pv.UnstructuredGrid
Workflow->>Saver: annotate field_data/cell_data and save per-group or combined .vtp/.vtu
Saver-->>User: paths of saved surface/mesh files

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐰 I hopped through code and data lanes,
Quiet quick_runs trimmed the chains.
CT to VTK, then meshes flew,
USDs dressed in colormap hue.
Small rabbit clap — the pipeline grew!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title references colormap consistency for Alterra and TPV25 valves, which is addressed in the corresponding notebook changes, but the commit message and most substantial changes focus on a CT-to-VTK segmentation workflow that is unrelated to the title's stated objective. Update the PR title to accurately reflect the primary changes, such as 'ENH: Add CT-to-VTK segmentation workflow and colormap updates' or split into separate PRs for colormap vs. segmentation features.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 96.77% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the valve USD-generation experiment notebooks to apply a consistent stress/strain-to-color mapping (fixed intensity range + chosen colormap + sigmoid normalization) when post-processing simulation primvars into displayColor.

Changes:

  • Set a fixed intensity_range=(25, 200) when applying colormaps from stress/strain primvars.
  • Switch colormap selection to "jet" for these valve conversions.
  • Enable use_sigmoid_scale=True to apply sigmoid normalization before colormap lookup.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb Updates the post-processing colormap application parameters for TPV25 valve USD output.
experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.ipynb Updates the post-processing colormap application parameters for Alterra valve USD output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb (1)

388-390: Use a shared colormap preset instead of hardcoded literals in this call.

This works, but these literals can drift from other TPV25 colorization paths in the same notebook. A single preset keeps the mapping policy truly consistent.

♻️ Suggested refactor
 # Configuration: choose colormap for visualization
 DEFAULT_COLORMAP = "viridis"  # matplotlib colormap name
+VALVE_STRESS_COLORMAP = {
+    "intensity_range": (25, 200),
+    "cmap": "jet",
+    "use_sigmoid_scale": True,
+}
@@
             usd_tools.apply_colormap_from_primvar(
                 str(output_usd),
                 mesh_path1,
                 color_primvar,
-                intensity_range=(25, 200),
-                cmap="jet",
-                use_sigmoid_scale=True,
+                intensity_range=VALVE_STRESS_COLORMAP["intensity_range"],
+                cmap=VALVE_STRESS_COLORMAP["cmap"],
+                use_sigmoid_scale=VALVE_STRESS_COLORMAP["use_sigmoid_scale"],
                 bind_vertex_color_material=True,
             )
@@
             usd_tools.apply_colormap_from_primvar(
                 str(output_usd_sub),
                 mesh_path,
                 color_primvar,
-                cmap=DEFAULT_COLORMAP,
+                intensity_range=VALVE_STRESS_COLORMAP["intensity_range"],
+                cmap=VALVE_STRESS_COLORMAP["cmap"],
+                use_sigmoid_scale=VALVE_STRESS_COLORMAP["use_sigmoid_scale"],
                 bind_vertex_color_material=True,
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb` around
lines 388 - 390, Replace the hardcoded parameters intensity_range=(25, 200),
cmap="jet", use_sigmoid_scale=True with a single shared colormap preset (e.g.,
TPV25_COLORMAP_PRESET or get_tpv25_colormap_preset()) and pass that preset into
the call; update the call site that currently supplies intensity_range, cmap and
use_sigmoid_scale to instead read those values from the preset so all TPV25
colorization paths share the same mapping policy.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb`:
- Around line 388-390: Replace the hardcoded parameters intensity_range=(25,
200), cmap="jet", use_sigmoid_scale=True with a single shared colormap preset
(e.g., TPV25_COLORMAP_PRESET or get_tpv25_colormap_preset()) and pass that
preset into the call; update the call site that currently supplies
intensity_range, cmap and use_sigmoid_scale to instead read those values from
the preset so all TPV25 colorization paths share the same mapping policy.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a956ff7 and 9f4d295.

📒 Files selected for processing (2)
  • experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.ipynb
  • experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 1, 2026

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.ipynb`:
- Line 202: The section header "## 3. Convert TPV25" is incorrect; update the
notebook markdown cell that contains that exact string (the header "## 3.
Convert TPV25") to accurately describe the conversion being performed, e.g.
change it to "## 3. Convert Alterra" or "## 3. Convert Alterra valve to USD" so
the section title matches the Alterra conversion code and context.
- Around line 134-142: The code collects matches into alterra_series from
vtk_files using pattern but doesn't handle the case where no frames match;
before any access (e.g., before using alterra_series[0] later), check if
alterra_series is empty and raise a clear, dataset-specific exception (e.g.,
ValueError or a custom AlterraDatasetError) with a message that includes the
pattern and the source directory or vtk_files summary so callers can diagnose
missing frames/naming drift; perform this check immediately after
alterra_series.sort(...) and before downstream uses.
- Around line 96-99: The colormap configuration currently allows both "stress"
and "strain" in colormap_primvar_substrs which can silently pick strain and
misapply the fixed colormap_range_min/colormap_range_max; change
colormap_primvar_substrs to only ["stress"] and ensure downstream usage (where
colormap_name, colormap_range_min, colormap_range_max are applied) is based on
that stress-only list (or add a simple assertion that the selected primvar
equals "stress") so the fixed (25,200) range is only used for stress
visualizations.

In `@experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb`:
- Around line 258-263: The code pins vessel_path to a specific prim name
("TPV25Valve_object4"), which is brittle; instead detect the correct mesh prim
under the TPV25Valve meshes at runtime. Modify the logic around
conversion_settings.separate_objects_by_connectivity /
separate_objects_by_cell_type to enumerate children of
"/World/Meshes/TPV25Valve" (or the parent used), inspect prim names/attributes
or topology/point-count to find the intended mesh (e.g., the prim whose
topology/face-count or connectivity attribute matches the source VTK component),
and set vessel_path to that discovered prim path before the primvar lookup that
follows (the variable currently named vessel_path and the primvar query that
relies on it). Ensure fallback to the single mesh path when no separate objects
exist.
- Around line 132-140: The code collects matching VTK files into tpv25_series by
iterating over vtk_files with the regex pattern and then sorts it; add a guard
after tpv25_series.sort(...) that checks if tpv25_series is empty and raise a
FileNotFoundError with a clear message (including pattern and/or input directory
context) so later access like tpv25_series[0] fails fast and provides actionable
information. Ensure the check references the same variable name tpv25_series and
include enough context in the exception message to identify the missing TPV25
frames.
- Around line 94-97: The colormap source list colormap_primvar_substrs currently
allows both "stress" and "strain", which can let TPV25 use a different scalar
while still using the same colormap bounds
(colormap_range_min/colormap_range_max) and thus break the "consistent stress
colormap" requirement; update colormap_primvar_substrs to include only "stress"
so the notebook always uses stress as the scalar for colorization (leave
colormap_name and colormap_range_min/colormap_range_max as-is unless there’s a
separate range for strain to adjust).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fa01d113-592b-4898-bd09-464f5e215eae

📥 Commits

Reviewing files that changed from the base of the PR and between 9f4d295 and 6e9eefa.

📒 Files selected for processing (2)
  • experiments/Convert_VTK_To_USD/convert_chop_alterra_valve_to_usd.ipynb
  • experiments/Convert_VTK_To_USD/convert_chop_tpv25_valve_to_usd.ipynb

 Introduces WorkflowConvertCTToVTK, which segments a 3D CT using a
 configurable backend (TotalSegmentator, VISTA-3D, or Simpleware) and
 exports per-anatomy-group VTP surfaces and VTU voxel meshes annotated
 with anatomy labels and colors. Adds a matching CLI command
 (physiomotion4d-convert-ct-to-vtk) and a stage-free
 USDAnatomyTools.get_anatomy_diffuse_color() accessor used by the new
 workflow.
Copilot AI review requested due to automatic review settings March 28, 2026 11:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (3)
experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb (1)

12-12: Consider removing the os import.

If the path cleanup is refactored to use pathlib methods (.exists() and .unlink()), this import becomes unused and can be removed.

 from pathlib import Path
 
-import os
-
 from physiomotion4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb` at line
12, Remove the unused "import os" at the top of the notebook and refactor any
path cleanup code that still uses os functions to use pathlib.Path methods
(e.g., replace os.path.exists / os.remove with Path.exists() and Path.unlink())
so the os import is no longer needed; search for usages around the path cleanup
logic and update the code to call Path(...).exists() and Path(...).unlink()
instead.
src/physiomotion4d/segment_heart_simpleware.py (1)

327-330: Consider returning a copy from get_landmarks() to avoid external mutation of internal state.

Current implementation exposes mutable internal state directly.

♻️ Small defensive refactor
     def get_landmarks(self) -> dict[str, tuple[float, float, float]]:
         """Get the landmarks."""
-        return self.landmarks
+        return dict(self.landmarks)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/physiomotion4d/segment_heart_simpleware.py` around lines 327 - 330, The
get_landmarks method currently returns the internal mutable dict self.landmarks
directly; change it to return a defensive copy to prevent external mutation
(e.g., return a shallow copy of the dict so callers can't modify the internal
mapping). Update the get_landmarks function to return a copy of self.landmarks
(or a deep copy if landmarks values may later become mutable) while keeping the
same return type and behavior otherwise.
src/physiomotion4d/workflow_fit_statistical_model_to_patient.py (1)

207-208: Update setter docstrings to match new defaults.

The default values have changed, but the docstrings at lines 335 and 344 still reference the old defaults ("Default: 5mm" and "Default: 20mm").

📝 Proposed docstring updates

At line 335:

-                Default: 5mm
+                Default: 0mm

At line 344:

-                Default: 20mm
+                Default: 25mm
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/physiomotion4d/workflow_fit_statistical_model_to_patient.py` around lines
207 - 208, Update the docstrings for the setter properties that document
mask_dilation_mm and roi_dilation_mm to reflect the new defaults: change the
mask_dilation_mm setter docstring default from "Default: 5mm" to "Default:
0.0mm" and change the roi_dilation_mm setter docstring default from "Default:
20mm" to "Default: 25.0mm"; locate the setters that reference mask_dilation_mm
and roi_dilation_mm (the property/method names for those setters) and update
their docstring default lines only so the docs match the actual defaults
assigned in the initializer.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Around line 55-57: The fenced code block containing "4D CT → Segmentation →
Registration → Contour Extraction → USD Export" needs a language tag to satisfy
markdownlint MD040; update the fence opening from ``` to ```text (or another
appropriate language) so the block becomes a labeled code fence (refer to the
existing fenced block content in CLAUDE.md).

In `@experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb`:
- Around line 45-46: The cleanup currently checks and removes
RVOT28-Dias-{usdname}.usd in the CWD using Path.absolute(Path(...)) and
os.path.exists/os.remove, which doesn't match the later write to output_dir;
update the cleanup to target the same output_dir by building the target path via
output_dir / f"RVOT28-Dias-{usdname}.usd" (or output_dir.joinpath(...)) and use
pathlib's exists() and unlink() methods instead of os.path.exists/os.remove to
delete any stale file before writing; adjust references around usdname and
output_dir to ensure the same path is used for both cleanup and file creation.

In
`@experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.ipynb`:
- Around line 124-128: The notebook saves the UnstructuredGrid stored in
results["registered_template_model"] to a .vtp file which is incorrect; change
the save call for registered_model to write a .vtu file while leaving
registered_model_surface (PolyData) saved as .vtp. Locate the symbols
registered_model (from results["registered_template_model"]) and
registered_model_surface (from results["registered_template_model_surface"]) and
update the registered_model.save invocation to use "registered_model.vtu"
(keeping output_dir and the existing path construction).

In `@experiments/Reconstruct4DCT/reconstruct_4d_ct_class.ipynb`:
- Around line 87-94: The comment and enabled methods are inverted: restore ICON
and ants_icon to the full-run configuration by updating registration_methods
(currently ["ants"]) to include "icon" and "ants_icon" and align
number_of_iterations_list to include the corresponding iteration settings for
each method (match entries to "ants", "icon", and "ants_icon"), and update the
preceding comment text (the string on line with registration_methods) to
accurately describe that full_run includes ANTs, ICON, and ants_icon;
alternatively, if you prefer to keep quick_run with fewer methods, remove "icon"
and "ants_icon" from the quick_run list (the variable quick_run referenced
earlier) so the quick-run and full-run semantics are consistent.

In `@src/physiomotion4d/contour_tools.py`:
- Around line 179-182: The code assumes mesh.n_faces_strict > 0 and uniformly
triangulated faces; add a guard in the contour processing path (where
extract_contours() may return an empty mesh) to early-return or set
faces/vertices to empty when mesh.n_faces_strict == 0, and before computing
num_points_per_face and reshaping ensure the mesh is explicitly triangulated
(call the triangulation helper or convert polygonal faces to triangles) and
validate that len(mesh.faces) is divisible by mesh.n_faces_strict; update the
block referencing mesh.faces and mesh.n_faces_strict to perform these checks and
triangulation so the reshape cannot raise ZeroDivisionError or produce
mis-shaped arrays.

In `@src/physiomotion4d/segment_heart_simpleware.py`:
- Around line 286-297: The code unconditionally opens and parses landmarks_file
which makes the whole segmentation fail if landmarks.csv is missing or
malformed; modify the block around landmarks_file and self.landmarks.clear() to
be resilient: first check os.path.exists(landmarks_file) or wrap the open/csv
parsing in a try/except that catches FileNotFoundError, csv.Error and
ValueError, log a warning and leave self.landmarks empty (do not re-raise), and
when parsing each row validate coords length and numeric conversion before
assigning to self.landmarks so malformed rows are skipped with a warning; refer
to landmarks_file, self.landmarks.clear(), csv.DictReader and the
Measurement/Name parsing to locate the code to change.

In `@src/physiomotion4d/workflow_fit_statistical_model_to_patient.py`:
- Around line 155-167: The code assumes patient_models_data["meshes"]["heart"]
always exists after calling WorkflowConvertCTToVTK.run_workflow; update the
branch that sets patient_models to first heart mesh to first check that "meshes"
in patient_models_data and "heart" in patient_models_data["meshes"] and that
patient_models_data["meshes"]["heart"] is non-empty, and if any check fails
raise a clear ValueError (or fallback) indicating the heart mesh was not
produced and advising to provide patient_models or verify segmentation settings;
reference the WorkflowConvertCTToVTK.run_workflow call and the
patient_models_data / patient_models variables when implementing the guard.

---

Nitpick comments:
In `@experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb`:
- Line 12: Remove the unused "import os" at the top of the notebook and refactor
any path cleanup code that still uses os functions to use pathlib.Path methods
(e.g., replace os.path.exists / os.remove with Path.exists() and Path.unlink())
so the os import is no longer needed; search for usages around the path cleanup
logic and update the code to call Path(...).exists() and Path(...).unlink()
instead.

In `@src/physiomotion4d/segment_heart_simpleware.py`:
- Around line 327-330: The get_landmarks method currently returns the internal
mutable dict self.landmarks directly; change it to return a defensive copy to
prevent external mutation (e.g., return a shallow copy of the dict so callers
can't modify the internal mapping). Update the get_landmarks function to return
a copy of self.landmarks (or a deep copy if landmarks values may later become
mutable) while keeping the same return type and behavior otherwise.

In `@src/physiomotion4d/workflow_fit_statistical_model_to_patient.py`:
- Around line 207-208: Update the docstrings for the setter properties that
document mask_dilation_mm and roi_dilation_mm to reflect the new defaults:
change the mask_dilation_mm setter docstring default from "Default: 5mm" to
"Default: 0.0mm" and change the roi_dilation_mm setter docstring default from
"Default: 20mm" to "Default: 25.0mm"; locate the setters that reference
mask_dilation_mm and roi_dilation_mm (the property/method names for those
setters) and update their docstring default lines only so the docs match the
actual defaults assigned in the initializer.
🪄 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

Run ID: 2c0dbd97-9175-438e-89e8-c1f217a15854

📥 Commits

Reviewing files that changed from the base of the PR and between 6e9eefa and 781a3e1.

📒 Files selected for processing (15)
  • CLAUDE.md
  • data/DirLab-4DCT/.gitignore
  • experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.ipynb
  • experiments/Heart-Statistical_Model_To_Patient/heart_model_to_patient-CHOPValve.ipynb
  • experiments/Reconstruct4DCT/reconstruct_4d_ct_class.ipynb
  • pyproject.toml
  • src/physiomotion4d/__init__.py
  • src/physiomotion4d/cli/convert_ct_to_vtk.py
  • src/physiomotion4d/contour_tools.py
  • src/physiomotion4d/register_images_icon.py
  • src/physiomotion4d/segment_heart_simpleware.py
  • src/physiomotion4d/simpleware_medical/SimplewareScript_heart_segmentation.py
  • src/physiomotion4d/usd_anatomy_tools.py
  • src/physiomotion4d/workflow_convert_ct_to_vtk.py
  • src/physiomotion4d/workflow_fit_statistical_model_to_patient.py
✅ Files skipped from review due to trivial changes (1)
  • data/DirLab-4DCT/.gitignore

@aylward aylward merged commit d2325e1 into Project-MONAI:main Mar 28, 2026
18 checks passed
@aylward aylward deleted the ColormapValves branch March 28, 2026 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants