Examples
This page provides quick examples for common PhysioMotion4D use cases. For detailed workflow guides, see the CLI & Scripts Overview section.
Note
For Production Workflows: The CLI commands (physiomotion4d-heart-gated-ct,
physiomotion4d-create-statistical-model, physiomotion4d-fit-statistical-model-to-patient)
and their implementations in src/physiomotion4d/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
not be used as usage examples. They may contain outdated APIs, hardcoded paths, and minimal
error handling. Consult these experiments only as conceptual references when adapting
workflows to new anatomical regions or digital twin applications.
Complete Workflow Examples
Heart-Gated CT Processing
Complete end-to-end cardiac CT processing:
from physiomotion4d import WorkflowConvertHeartGatedCTToUSD
# Initialize workflow
workflow = WorkflowConvertHeartGatedCTToUSD(
input_filenames=["cardiac_4d.nrrd"],
contrast_enhanced=True,
output_directory="./results",
project_name="patient_001",
registration_method="ants",
)
# Run complete workflow
final_usd = workflow.process()
print(f"Generated USD model: {final_usd}")
Lung 4D-CT Reconstruction
Reconstruct a high-resolution 4D CT sequence from manually prepared respiratory phase images:
from pathlib import Path
import itk
from physiomotion4d import WorkflowReconstructHighres4DCT
# DirLab-4DCT data is manual-only. Place phase images under ./data/DirLab.
phase_dir = Path("./data/DirLab/case1")
phase_files = sorted(list(phase_dir.glob("*.mhd")) + list(phase_dir.glob("*.mha")))
time_series_images = [itk.imread(str(path)) for path in phase_files]
fixed_image = time_series_images[0]
workflow = WorkflowReconstructHighres4DCT(
time_series_images=time_series_images,
fixed_image=fixed_image,
reference_frame=0,
registration_method="ants",
)
result = workflow.run_workflow(upsample_to_fixed_resolution=True)
reconstructed_images = result["reconstructed_images"]
Segmentation Examples
TotalSegmentator
Quick segmentation with TotalSegmentator:
from physiomotion4d import SegmentChestTotalSegmentator
import itk
# Load image
image = itk.imread("chest_ct.nrrd")
# Segment
segmenter = SegmentChestTotalSegmentator()
masks = segmenter.segment(image, contrast_enhanced_study=True)
# Extract masks by anatomy group
heart = masks["heart"]
lungs = masks["lung"]
vessels = masks["major_vessels"]
labelmap = masks["labelmap"]
# Save results
itk.imwrite(heart, "heart_mask.nrrd")
itk.imwrite(lungs, "lungs_mask.nrrd")
itk.imwrite(vessels, "major_vessels_mask.nrrd")
itk.imwrite(labelmap, "labelmap.nrrd")
Registration Examples
ICON Deep Learning Registration
Fast GPU-accelerated registration:
from physiomotion4d.register_images_icon import RegisterImagesICON
import itk
# Initialize
registerer = RegisterImagesICON()
registerer.set_modality('ct')
registerer.set_number_of_iterations(100)
# Load images
fixed = itk.imread("frame_000.mha")
moving = itk.imread("frame_005.mha")
# Register
registerer.set_fixed_image(fixed)
results = registerer.register(moving)
# Get results
inverse_transform = results["inverse_transform"]
forward_transform = results["forward_transform"]
registered = registerer.get_registered_image()
# Save
itk.imwrite(registered, "registered.mha")
itk.transformwrite(forward_transform, "transform_forward.hdf")
itk.transformwrite(inverse_transform, "transform_inverse.hdf")
Multi-Phase Cardiac Registration
Register all cardiac phases to reference:
from physiomotion4d.register_images_icon import RegisterImagesICON
import itk
import glob
registerer = RegisterImagesICON()
registerer.set_modality('ct')
# Load reference (e.g., end-diastole)
reference = itk.imread("frame_000.mha")
registerer.set_fixed_image(reference)
# Register all phases
frame_files = sorted(glob.glob("frame_*.mha"))
transforms = []
for frame_file in frame_files[1:]: # Skip reference
moving = itk.imread(frame_file)
results = registerer.register(moving)
transforms.append(results["inverse_transform"])
print(f"Registered {frame_file}: loss = {results['loss']:.3f}")
ANTs Multi-Stage Registration
Advanced registration with multiple stages:
from physiomotion4d import RegisterImagesANTs
import itk
registerer = RegisterImagesANTs()
fixed = itk.imread("reference.mha")
moving = itk.imread("target.mha")
registerer.set_fixed_image(fixed)
registerer.set_modality('ct')
registerer.set_transform_type('SyN')
# Perform registration with SyN (Symmetric Normalization)
result = registerer.register(moving)
USD Conversion Examples
VTK Time Series to USD
Convert VTK mesh sequence to animated USD:
from physiomotion4d import ConvertVTKToUSD
import glob
# Get VTK files
vtk_files = sorted(glob.glob("heart_frame_*.vtp"))
time_codes = [float(i) for i in range(len(vtk_files))]
stage = ConvertVTKToUSD.from_files(
data_basename="Heart",
vtk_files=vtk_files,
time_codes=time_codes,
times_per_second=30,
).convert("heart_animation.usd")
print("USD animation created: heart_animation.usd")
Merge Multiple USD Files
Combine separate anatomical structures:
from physiomotion4d import USDTools
tools = USDTools()
# Merge USD files
files = [
"heart_dynamic.usd",
"lungs_dynamic.usd",
"vessels_static.usd",
"bones_static.usd"
]
tools.merge_usd_files("complete_thorax.usd", files)
Apply Materials to USD
Add anatomical materials and colors:
from physiomotion4d import USDAnatomyTools
from pxr import Usd
stage = Usd.Stage.Open("thorax_model.usd")
painter = USDAnatomyTools(stage)
painter.apply_anatomy_material_to_mesh("/World/Heart", "heart")
painter.apply_anatomy_material_to_mesh("/World/Aorta", "major_vessels")
painter.apply_anatomy_material_to_mesh("/World/LeftLung", "lung")
painter.apply_anatomy_material_to_mesh("/World/RightLung", "lung")
painter.apply_anatomy_material_to_mesh("/World/Ribs", "bone")
stage.Export("thorax_painted.usd")
Transform and Contour Examples
Apply Transform to Images
Warp images using deformation fields:
from physiomotion4d import TransformTools
import itk
tools = TransformTools()
# Load transform, moving image, and reference image
phi = itk.transformread("transform_forward.hdf")
moving_image = itk.imread("moving_image.mha")
reference_image = itk.imread("reference_image.mha")
# Apply transform
warped = tools.transform_image(moving_image, phi, reference_image)
# Save result
itk.imwrite(warped, "warped_image.mha")
Transform Contours/Meshes
Propagate segmentation contours across time:
from physiomotion4d import TransformTools
import itk
import pyvista as pv
tools = TransformTools()
# Load reference contour and transforms
reference_mesh = pv.read("heart_t0.vtp")
# Transform to each time point
for t in range(1, 10):
phi = itk.transformread(f"transform_t0_to_t{t}.hdf")
warped_mesh = tools.transform_pvcontour(reference_mesh, phi)
warped_mesh.save(f"heart_t{t}.vtp")
Extract Surface from Segmentation
Convert segmentation masks to meshes:
from physiomotion4d import ContourTools
import itk
tools = ContourTools()
# Load segmentation
mask = itk.imread("heart_segmentation.nrrd")
# Extract smoothed contour surface
mesh = tools.extract_contours(mask)
# Save mesh
mesh.save("heart_surface.vtp")
Visualization Examples
Quick Preview in PyVista
Visualize meshes and images:
import pyvista as pv
import itk
import numpy as np
# Visualize mesh
mesh = pv.read("heart.vtp")
mesh.plot(color='red', opacity=0.8)
# Visualize image slice
image = itk.imread("ct_scan.nrrd")
array = itk.array_from_image(image)
pl = pv.Plotter()
pl.add_volume(array, cmap='bone')
pl.show()
Animated Mesh Sequence
Create animation from mesh sequence:
import pyvista as pv
import glob
# Load mesh sequence
mesh_files = sorted(glob.glob("heart_t*.vtp"))
pl = pv.Plotter()
pl.open_gif("heart_animation.gif")
# Animate
meshes = [pv.read(f) for f in mesh_files]
for i in range(len(meshes)):
pl.clear()
pl.add_mesh(meshes[i], color='red')
pl.write_frame()
pl.close()
Batch Processing Examples
Process Multiple Patients
Batch process multiple datasets:
from physiomotion4d import WorkflowConvertHeartGatedCTToUSD
import glob
import os
# Find all patient data
patient_dirs = glob.glob("data/patient_*")
for patient_dir in patient_dirs:
patient_id = os.path.basename(patient_dir)
input_file = os.path.join(patient_dir, "cardiac_4d.nrrd")
if not os.path.exists(input_file):
continue
print(f"Processing {patient_id}...")
workflow = WorkflowConvertHeartGatedCTToUSD(
input_filenames=[input_file],
contrast_enhanced=True,
output_directory=f"results/{patient_id}",
project_name=patient_id,
registration_method="ants",
)
try:
final_usd = workflow.process()
print(f" Complete: {final_usd}")
except Exception as e:
print(f" Failed: {e}")
Parallel Segmentation
Segment multiple images in parallel:
from physiomotion4d import SegmentChestTotalSegmentator
import itk
import glob
from concurrent.futures import ProcessPoolExecutor
def segment_image(filename):
segmenter = SegmentChestTotalSegmentator()
image = itk.imread(filename)
result = segmenter.segment(image, contrast_enhanced_study=True)
# Save heart mask
output_name = filename.replace('.nrrd', '_heart.nrrd')
itk.imwrite(result['heart'], output_name)
return output_name
# Process in parallel
image_files = glob.glob("data/*.nrrd")
max_workers = 1 # Increase only when each worker has enough CPU/GPU memory.
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(segment_image, image_files))
print(f"Segmented {len(results)} images")
Data Download Examples
Download Slicer-Heart Dataset
from physiomotion4d import DataDownloadTools
data_file = DataDownloadTools.DownloadSlicerHeartCTData("data/Slicer-Heart-CT")
assert DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT")
Custom Workflow Examples
Complete Workflow Processing
Run the supported end-to-end workflow API:
from physiomotion4d import WorkflowConvertHeartGatedCTToUSD
workflow = WorkflowConvertHeartGatedCTToUSD(
input_filenames=["cardiac_4d.nrrd"],
contrast_enhanced=True,
output_directory="./results",
project_name="cardiac_model",
registration_method="ants",
)
final_usd = workflow.process()
print(f"Complete: {final_usd}")
Custom Pipeline with Specific Methods
Mix and match different components:
from physiomotion4d import (
SegmentChestTotalSegmentator,
RegisterImagesICON,
TransformTools,
ConvertVTKToUSD,
ContourTools
)
import itk
# Load images
reference = itk.imread("frame_000.mha")
frames = [itk.imread(f"frame_{i:03d}.mha") for i in range(10)]
# Segment reference
segmenter = SegmentChestTotalSegmentator()
result = segmenter.segment(reference, contrast_enhanced_study=True)
heart_mask = result['heart']
# Extract reference contour
contour_tools = ContourTools()
reference_mesh = contour_tools.extract_contours(heart_mask)
# Register and transform
registerer = RegisterImagesICON()
registerer.set_modality('ct')
registerer.set_fixed_image(reference)
transform_tools = TransformTools()
meshes = [reference_mesh]
for frame in frames[1:]:
results = registerer.register(frame)
warped_mesh = transform_tools.transform_pvcontour(
reference_mesh,
results["inverse_transform"]
)
meshes.append(warped_mesh)
# Save meshes
for i, mesh in enumerate(meshes):
mesh.save(f"heart_{i:03d}.vtp")
vtk_files = [f"heart_{i:03d}.vtp" for i in range(10)]
time_codes = [float(i) for i in range(len(vtk_files))]
stage = ConvertVTKToUSD.from_files(
data_basename="Heart",
vtk_files=vtk_files,
time_codes=time_codes,
).convert("heart.usd")
See Also
CLI & Scripts Overview - Detailed command-line workflows
API Reference - Complete API reference
Heart Gated CT Processing - Heart-gated CT guide
Troubleshooting - Common issues and solutions