Workflow Classes

Workflow classes are the highest-level Python API in PhysioMotion4D. They combine segmentation, registration, contour generation, and USD conversion into repeatable pipelines. The installed CLI commands are thin wrappers around these classes.

Available Workflows

Workflow

Typical use

WorkflowConvertHeartGatedCTToUSD

Convert a 4D cardiac CT sequence into animated USD anatomy.

WorkflowConvertCTToVTK

Segment one CT image and export anatomy-group VTK surfaces and meshes.

WorkflowConvertVTKToUSD

Convert VTK/VTP/VTU meshes or time series into USD.

WorkflowCreateStatisticalModel

Build a PCA shape model from sample meshes aligned to a reference.

WorkflowFitStatisticalModelToPatient

Fit a template/statistical heart model to patient-specific surfaces.

WorkflowReconstructHighres4DCT

Reconstruct a high-resolution 4D CT series from phase images and a high-resolution reference.

Heart-Gated CT to USD

class physiomotion4d.WorkflowConvertHeartGatedCTToUSD(input_filenames, contrast_enhanced, output_directory, project_name, reference_image_filename=None, number_of_registration_iterations=1, registration_method='icon', log_level=20, save_registered_images=True, save_registration_transforms=True, save_labelmaps=True)[source]

Bases: PhysioMotion4DBase

Complete workflow for Heart-gated CT images to dynamic USD models.

This class implements the full workflow from 4D CT images to painted USD files suitable for visualization in NVIDIA Omniverse.

__init__(input_filenames, contrast_enhanced, output_directory, project_name, reference_image_filename=None, number_of_registration_iterations=1, registration_method='icon', log_level=20, save_registered_images=True, save_registration_transforms=True, save_labelmaps=True)[source]

Initialize the Heart-gated CT to USD workflow.

Parameters:
  • input_filenames (List) – List of paths to the 3D NRRD files containing cardiac CT data. If there is only one file, it will be used as the 4D NRRD file.

  • contrast_enhanced (bool) – Whether the study uses contrast enhancement

  • output_directory (str) – Directory path where output files will be stored

  • project_name (str) – Project name for USD file organization

  • reference_image_filename (Optional[str]) – Path to reference image file

  • number_of_registration_iterations (Optional[int]) – Number of registration iterations

  • registration_method (str) – Registration method to use: ‘ants’ or ‘icon’ (default: ‘icon’)

  • log_level (int | str) – Logging level (default: logging.INFO)

  • save_registered_images (bool) – Write registered image intermediates to output_directory when True

  • save_registration_transforms (bool) – Write registration transforms to output_directory when True

  • save_labelmaps (bool) – Write segmentation labelmaps and registration masks to output_directory when True

process()[source]

Execute the complete workflow from 4D CT to dynamic USD models.

Returns:

Path to the final dynamic anatomy USD file

Return type:

str

from physiomotion4d import WorkflowConvertHeartGatedCTToUSD

workflow = WorkflowConvertHeartGatedCTToUSD(
    input_filenames=["cardiac_4d.nrrd"],
    contrast_enhanced=True,
    output_directory="./results",
    project_name="patient_001",
    registration_method="ants",
)

final_usd = workflow.process()

CT to VTK

class physiomotion4d.WorkflowConvertCTToVTK(segmentation_method='total_segmentator', log_level=20)[source]

Bases: PhysioMotion4DBase

Segment a CT image and produce per-anatomy-group VTK surfaces and meshes.

Segmentation backends

Output anatomy groups

heart, lung, major_vessels, bone, soft_tissue, other, contrast. Groups that are empty after segmentation are silently skipped.

VTK object annotation

Each pyvista.PolyData surface and pyvista.UnstructuredGrid mesh returned by run_workflow() carries:

  • field_data['AnatomyGroup'] — anatomy group name, e.g. 'heart'.

  • field_data['SegmentationLabelNames'] — individual structure names within the group (e.g. ['left_ventricle', 'right_ventricle', …]).

  • field_data['SegmentationLabelIds'] — corresponding integer label IDs.

  • field_data['AnatomyColor'] — RGB float color from USDAnatomyTools.

  • cell_data['Color'] — RGBA uint8 array (n_cells × 4) for direct VTK rendering.

I/O contract

run_workflow() performs no file I/O. Use the static helpers save_surfaces(), save_meshes(), save_combined_surface(), and save_combined_mesh() — or the CLI physiomotion4d-convert-ct-to-vtk — to write results to disk.

ANATOMY_GROUPS: tuple[str, ...] = ('heart', 'lung', 'major_vessels', 'bone', 'soft_tissue', 'other', 'contrast')

Valid anatomy group names.

SEGMENTATION_METHODS: tuple[str, ...] = ('total_segmentator', 'simpleware_heart')

Valid segmentation method identifiers.

__init__(segmentation_method='total_segmentator', log_level=20)[source]

Initialize the workflow.

Parameters:
  • segmentation_method (str) – Segmentation backend to use. One of 'total_segmentator' (default) or 'simpleware_heart'.

  • log_level (int | str) – Logging level. Default: logging.INFO.

Raises:

ValueError – If segmentation_method is not one of SEGMENTATION_METHODS.

run_workflow(input_image, contrast_enhanced_study=False, anatomy_groups=None)[source]

Segment the CT image and extract per-anatomy-group VTK objects.

Parameters:
  • input_image (Any) – Input 3D CT image (itk.Image).

  • contrast_enhanced_study (bool) – If True, an additional connected-component pass identifies contrast-enhanced blood. Default: False.

  • anatomy_groups (Optional[list[str]]) – Subset of anatomy groups to process. None (default) processes all non-empty groups. Valid names: 'heart', 'lung', 'major_vessels', 'bone', 'soft_tissue', 'other', 'contrast'.

Returns:

  • 'surfaces'dict[str, pv.PolyData]: smoothed surface per group.

  • 'meshes'dict[str, pv.UnstructuredGrid]: voxel mesh per group.

  • 'labelmap'itk.Image: detailed per-structure segmentation labelmap from the segmenter.

  • 'segmentation_masks'dict[str, itk.Image]: per-group binary masks used to produce the VTK objects.

Return type:

dict with the following keys

Raises:

ValueError – If any name in anatomy_groups is invalid.

static save_surfaces(surfaces, output_dir, prefix='')[source]

Save each group surface to its own VTP file.

Parameters:
  • surfaces (dict[str, PolyData]) – Mapping of anatomy group name → surface (from run_workflow()).

  • output_dir (str) – Directory to write files into (created if absent).

  • prefix (str) – Optional filename prefix. Each file is named {prefix}_{group}.vtp (or {group}.vtp when prefix is empty).

Return type:

dict[str, str]

Returns:

Mapping of anatomy group name → absolute path of the saved file.

static save_meshes(meshes, output_dir, prefix='')[source]

Save each group voxel mesh to its own VTU file.

Parameters:
  • meshes (dict[str, UnstructuredGrid]) – Mapping of anatomy group name → mesh (from run_workflow()).

  • output_dir (str) – Directory to write files into (created if absent).

  • prefix (str) – Optional filename prefix. Each file is named {prefix}_{group}.vtu (or {group}.vtu when prefix is empty).

Return type:

dict[str, str]

Returns:

Mapping of anatomy group name → absolute path of the saved file.

static save_combined_surface(surfaces, output_dir, prefix='')[source]

Merge all group surfaces into a single VTP file.

The merged mesh retains per-cell Color (RGBA uint8) from each group’s annotation, enabling colour-by-anatomy rendering in Paraview, PyVista, etc. Per-object field_data is not preserved in the merged file.

Parameters:
  • surfaces (dict[str, PolyData]) – Mapping of anatomy group name → surface.

  • output_dir (str) – Directory to write the file into (created if absent).

  • prefix (str) – Optional filename prefix. Output is {prefix}_surfaces.vtp (or surfaces.vtp when prefix is empty).

Return type:

str

Returns:

Absolute path to the saved VTP file.

Raises:

ValueError – If surfaces is empty.

static save_combined_mesh(meshes, output_dir, prefix='')[source]

Merge all group meshes into a single VTU file.

The merged mesh retains per-cell Color (RGBA uint8) from each group’s annotation. Per-object field_data is not preserved in the merged file.

Parameters:
  • meshes (dict[str, UnstructuredGrid]) – Mapping of anatomy group name → voxel mesh.

  • output_dir (str) – Directory to write the file into (created if absent).

  • prefix (str) – Optional filename prefix. Output is {prefix}_meshes.vtu (or meshes.vtu when prefix is empty).

Return type:

str

Returns:

Absolute path to the saved VTU file.

Raises:

ValueError – If meshes is empty.

import itk

from physiomotion4d import WorkflowConvertCTToVTK

image = itk.imread("chest_ct.nii.gz")
workflow = WorkflowConvertCTToVTK(segmentation_method="total_segmentator")
result = workflow.run_workflow(
    input_image=image,
    contrast_enhanced_study=True,
    anatomy_groups=["heart", "major_vessels"],
)

WorkflowConvertCTToVTK.save_combined_surface(
    result["surfaces"],
    "./output",
    prefix="patient01",
)

VTK to USD

class physiomotion4d.WorkflowConvertVTKToUSD(vtk_files, output_usd, *, separate_by_connectivity=True, separate_by_cell_type=False, mesh_name='Mesh', times_per_second=60.0, extract_surface=True, time_series_pattern='\\\\.t(\\\\d+)\\\\.(vtk|vtp|vtu)$', appearance='solid', solid_color=(0.8, 0.8, 0.8), anatomy_type='heart', colormap_primvar=None, colormap_name='viridis', colormap_intensity_range=None, log_level=20)[source]

Bases: PhysioMotion4DBase

Workflow to convert one or more VTK files to USD with configurable splitting and appearance (solid color, anatomic material, or colormap).

__init__(vtk_files, output_usd, *, separate_by_connectivity=True, separate_by_cell_type=False, mesh_name='Mesh', times_per_second=60.0, extract_surface=True, time_series_pattern='\\\\.t(\\\\d+)\\\\.(vtk|vtp|vtu)$', appearance='solid', solid_color=(0.8, 0.8, 0.8), anatomy_type='heart', colormap_primvar=None, colormap_name='viridis', colormap_intensity_range=None, log_level=20)[source]

Initialize the VTK-to-USD workflow.

Parameters:
  • vtk_files (list[str | Path]) – List of paths to VTK files (.vtk, .vtp, .vtu). One file = single frame; multiple files = time series (ordered by time_series_pattern).

  • output_usd (str | Path) – Path to output USD file.

  • separate_by_connectivity (bool) – If True, split mesh into separate objects by connectivity.

  • separate_by_cell_type (bool) – If True, split mesh by cell type (triangle/quad/…). Cannot be True when separate_by_connectivity is True.

  • mesh_name (str) – Base name for the mesh (or first mesh when not splitting).

  • times_per_second (float) – FPS for time-varying data.

  • extract_surface (bool) – For .vtu, extract surface before conversion.

  • time_series_pattern (str) – Regex to extract time index from filenames (one group).

  • appearance (Literal['solid', 'anatomy', 'colormap']) – “solid” | “anatomy” | “colormap”.

  • solid_color (tuple[float, float, float]) – RGB in [0,1] when appearance == “solid”.

  • anatomy_type (str) – Anatomy material name when appearance == “anatomy” (e.g. heart, lung, bone, soft_tissue).

  • colormap_primvar (str | None) – Primvar name for coloring when appearance == “colormap” (e.g. vtk_point_stress_c0). If None, a candidate is auto-picked when possible.

  • colormap_name (str) – Matplotlib colormap name when appearance == “colormap”.

  • colormap_intensity_range (tuple[float, float] | None) – Optional (vmin, vmax) for colormap; None = auto from data.

  • log_level (int | str) – Logging level.

discover_time_series(paths, pattern='\\\\.t(\\\\d+)\\\\.(vtk|vtp|vtu)$')[source]

Discover and sort time-series VTK files by extracted time index.

Parameters:
  • paths (list[Path]) – List of paths to VTK files

  • pattern (str) – Regex with one group for time step number (default matches .t123.vtk)

Returns:

Sorted list of (time_step, path) tuples, and a flag True only when every path matched the pattern (true time series). If any path does not match, time_series is [(0, p) for p in paths] and pattern_matched is False (static merge).

Return type:

(time_series, pattern_matched)

run()[source]

Run the full workflow: convert VTK to USD, then apply the chosen appearance.

Return type:

str

Returns:

Path to the created USD file (str).

from physiomotion4d import WorkflowConvertVTKToUSD

workflow = WorkflowConvertVTKToUSD(
    vtk_files=["heart_000.vtp", "heart_001.vtp"],
    output_usd="heart.usd",
    appearance="anatomy",
    anatomy_type="heart",
)

output_path = workflow.run()

Statistical Shape Modeling

class physiomotion4d.WorkflowCreateStatisticalModel(sample_meshes, reference_mesh, pca_number_of_components=15, reference_spatial_resolution=1.0, reference_buffer_factor=0.25, solve_for_surface_pca=True, log_level=20)[source]

Bases: PhysioMotion4DBase

Create a PCA statistical shape model from a sample of meshes aligned to a reference.

Pipeline:

  1. Extract surfaces from sample and reference meshes, or keep as meshes

  2. ICP alignment: align each sample surface to the reference (template) surface. Always extract surfaces for ICP alignment.

  3. Deformable registration: establish dense correspondence via mask-based SyN. Uses either full meshes or surfaces.

  4. Correspondence: warp reference model by each transform to get aligned shapes

  5. PCA: compute mean and modes from corresponded shapes

sample_meshes

List of sample mesh DataSets (.vtk/.vtu/.vtp geometry)

Type:

list

reference_mesh

Reference mesh; its surface is used for alignment

Type:

pv.DataSet

pca_number_of_components

Number of PCA components to retain

Type:

int

reference_spatial_resolution

Resolution for reference image from mesh

Type:

float

reference_buffer_factor

Buffer around mesh for reference image

Type:

float

__init__(sample_meshes, reference_mesh, pca_number_of_components=15, reference_spatial_resolution=1.0, reference_buffer_factor=0.25, solve_for_surface_pca=True, log_level=20)[source]

Initialize the create-statistical-model workflow.

Parameters:
  • sample_meshes (list[DataSet]) – List of sample mesh DataSets (PyVista PolyData or UnstructuredGrid).

  • reference_mesh (DataSet) – Reference mesh; its surface is used to align all samples.

  • pca_number_of_components (int) – Number of PCA components. Default 15.

  • reference_spatial_resolution (float) – Isotropic resolution (mm) for reference image. Default 1.0.

  • reference_buffer_factor (float) – Buffer factor around mesh for reference image. Default 0.25.

  • solve_for_surface_pca (bool) – Whether to reduce the reference mesh to a surface. Default True.

  • log_level (int | str) – Logging level.

set_pca_number_of_components(n)[source]

Set number of PCA components to retain.

Return type:

None

run_workflow()[source]

Run the full pipeline and return a dictionary of results (no file I/O).

Returns:

  • pca_mean_surface: pv.PolyData mean shape surface

  • pca_mean_mesh: pv.UnstructuredGrid reference volume mesh, or None if reference was surface-only

  • pca_model: dict with “explained_variance_ratio”, “eigenvalues”, “components” (same structure as pca_model.json)

  • pca_fitted: fitted sklearn PCA object

Return type:

dict with keys

class physiomotion4d.WorkflowFitStatisticalModelToPatient(template_model, patient_models=None, patient_image=None, segmentation_method='simpleware_heart', log_level=20)[source]

Bases: PhysioMotion4DBase

Register anatomical models using multi-stage ICP, mask-based, and image-based

registration.

This class provides a flexible workflow for registering generic anatomical models (e.g., cardiac models) to patient-specific surface models and images. The registration pipeline combines: - Initial model alignment using RegisterModelsICP (centroid + affine ICP) - Mask-based deformable registration using RegisterModelsDistanceMaps (ANTs/ICON) - Optional final mask-to-image refinement using Icon registration

Registration Pipeline:
  1. ICP Alignment: Rough affine alignment using RegisterModelsICP

  2. PCA Registration: Performs PCA-based shape fitting using

    RegisterModelsPCA

  3. Mask-to-Mask: Deformable registration using RegisterModelsDistanceMaps

  4. Mask-to-Image: Final refinement

Mask Configuration:

Masks are automatically generated from models if not provided by the user via set_masks(). Auto-generated masks use mask_dilation_mm parameter.

template_model

Generic anatomical model to be registered

Type:

pv.DataSet

template_model_surface

Surface extracted from template_model_surface

Type:

pv.PolyData

template_model_mask

Binary/multi-label mask for model model

Type:

itk.Image

template_model_roi

ROI mask for model model

Type:

itk.Image

patient_models

Patient-specific models

Type:

list of pv.DataSet

patient_model_surface

Primary patient model surface (first in list)

Type:

pv.PolyData

combined_patient_model

Merged patient models before surface extraction; used when pca_uses_surface=False.

Type:

pv.PolyData

patient_image

Reference image providing coordinate frame

Type:

itk.Image

patient_mask

Binary/multi-label mask for patient model

Type:

itk.Image

patient_roi

ROI mask for patient model

Type:

itk.Image

mask_dilation_mm

Dilation for mask generation

Type:

float

roi_dilation_mm

Dilation for ROI mask

Type:

float

transform_tools

Transform utilities

Type:

TransformTools

registrar_icon

ICON registration instance

Type:

RegisterImagesICON

registrar_ants

ANTs registration instance

Type:

RegisterImagesANTs

use_pca_registration

Whether PCA registration is enabled (set via set_use_pca_registration)

Type:

bool

pca_model

PCA model dict when PCA enabled; same structure as WorkflowCreateStatisticalModel output

Type:

dict

pca_number_of_modes

Number of PCA modes when PCA enabled

Type:

int

icp_forward_point_transform

ICP transforms

icp_inverse_point_transform

ICP inverse transforms

icp_template_model_surface

template model surface after ICP alignment

icp_template_model

template model (UnstructuredGrid) after ICP alignment

pca_coefficients

PCA shape coefficients (if PCA used)

pca_template_model

template model after PCA registration (if PCA used)

Type:

pv.DataSet

pca_template_model_surface

template model surface after PCA registration (if PCA used)

m2m_forward_transform

Mask-to-mask forward transform

m2m_inverse_transform

Mask-to-mask inverse transform

m2m_template_model_surface

template model surface after mask-to-mask registration

m2i_forward_transform

Mask-to-image forward transform

m2i_inverse_transform

Mask-to-image inverse transform

m2i_template_model_surface

template model surface after mask-to-image registration

m2i_template_labelmap

template labelmap after mask-to-image registration

registered_template_model

Final registered model

registered_template_model_surface

Final registered model surface

Example

>>> # Initialize with minimal parameters (no labelmap; no patient image -> reference created from patient models)
>>> registrar = WorkflowFitStatisticalModelToPatient(
...     template_model=heart_model,
...     patient_models=[lv_model, mc_model, rv_model],
... )
>>> registrar.set_roi_dilation_mm(20)
>>> # To enable PCA registration, call before run_workflow():
>>> # registrar.set_use_pca_registration(True, pca_model=pca_model_dict, pca_number_of_modes=10)
>>> # To enable mask-to-image refinement:
>>> # registrar.set_use_mask_to_image_registration(True, template_labelmap, organ_mesh_ids, organ_extra_ids, background_ids)
>>> result = registrar.run_workflow()
__init__(template_model, patient_models=None, patient_image=None, segmentation_method='simpleware_heart', log_level=20)[source]

Initialize the model-to-image-and-model registration pipeline.

Parameters:
  • template_model (DataSet) – Generic anatomical model to be registered

  • patient_models (list[DataSet] | None) – List of patient-specific models extracted from imaging data. Typically 3 models for cardiac applications: LV, myocardium, RV.

  • patient_image (Optional[Image]) – Optional patient image providing the target coordinate frame. If None, a reference image is created from the patient model surface via create_reference_image (contour_tools).

  • log_level (int | str) – Logging level (logging.DEBUG, logging.INFO, logging.WARNING). Default: logging.INFO

set_mask_dilation_mm(mask_dilation_mm)[source]

Set mask dilation amount for auto-generated masks.

Parameters:

mask_dilation_mm (float) – Dilation amount in millimeters for mask generation. Default: 5mm

Return type:

None

set_roi_dilation_mm(roi_dilation_mm)[source]

Set ROI mask dilation amount.

Parameters:

roi_dilation_mm (float) – Dilation amount in millimeters for ROI mask generation. Default: 20mm

Return type:

None

set_use_pca_registration(use_pca_registration, pca_model=None, pca_number_of_modes=0, pca_uses_surface=True)[source]

Set whether to use PCA-based registration and provide the PCA model.

When enabling (True), pca_model and pca_number_of_modes must be provided.

Parameters:
  • use_pca_registration (bool) – Whether to use PCA registration after ICP.

  • pca_model (Optional[dict[str, Any]]) – Required when use is True. PCA model dict (e.g. from WorkflowCreateStatisticalModel result[“pca_model”]) with keys “eigenvalues” and “components”.

  • pca_number_of_modes (int) – Required when use is True. Number of PCA modes to use. Default 0 means use all modes.

Raises:

ValueError – If use is True and pca_model is None.

Return type:

None

set_use_mask_to_mask_registration(use_mask_to_mask_registration)[source]

Set whether to use mask-to-mask registration.

Parameters:

use_mask_to_mask_registration (bool) – Whether to use mask-to-mask registration. Default: True

Return type:

None

set_use_mask_to_image_registration(use_mask_to_image_registration, template_labelmap=None, template_labelmap_organ_mesh_ids=None, template_labelmap_organ_extra_ids=None, template_labelmap_background_ids=None)[source]

Set whether to use mask-to-image registration.

When enabling (True), a template labelmap and label IDs must be provided so the workflow can propagate and refine the labelmap to the patient image.

Parameters:
  • use_mask_to_image_registration (bool) – Whether to use mask-to-image registration.

  • template_labelmap (Optional[Image]) – Required when use is True. Template labelmap in template model space (same geometry as template_model).

  • template_labelmap_organ_mesh_ids (Optional[list[int]]) – Required when use is True. Label IDs for organ mesh in the template labelmap.

  • template_labelmap_organ_extra_ids (Optional[list[int]]) – Required when use is True. Label IDs for organ-extra structures in the template labelmap.

  • template_labelmap_background_ids (Optional[list[int]]) – Required when use is True. Label IDs for background in the template labelmap.

Raises:

ValueError – If use is True and any of template_labelmap or the id lists is None or missing.

Return type:

None

register_model_to_model_icp()[source]

Perform ICP alignment of template model to patient model.

Uses RegisterModelsICP class for ICP alignment.

Returns:

Dictionary containing:
  • ’forward_transform’: used to warp an image from model to patient space

  • ’inverse_transform’: used to warp an image from patient to model space

  • ’registered_template_model_surface’: Transformed model model surface

Return type:

dict

register_model_to_model_pca()[source]

Perform PCA-based registration after ICP alignment.

Uses RegisterModelsPCA class for intensity-based PCA registration. This method requires PCA data to be set via set_pca_data().

Returns:

Dictionary containing:
  • ’forward_point_transform’: Rigid transform from PCA registration

  • ’pca_coefficients’: PCA shape coefficients

  • ’registered_template_model_surface’: PCA-registered model surface

Return type:

dict

Raises:

ValueError – If PCA data has not been set

register_mask_to_mask(use_icon_refinement=False)[source]

Perform mask-based deformable registration of model to patient model.

Uses RegisterModelsDistanceMaps class for ANTs deformable registration.

Returns:

Dictionary containing:
  • ’forward_transform’: model to patient space transform

  • ’inverse_transform’: patient to model space transform

  • ’registered_template_model_surface’: Transformed model model

  • ’registered_template_labelmap’: Transformed model labelmap

Return type:

dict

register_labelmap_to_image(use_icon_refinement=False)[source]

Perform labelmap-to-image refinement.

Uses registration to align labelmap to actual image intensities.

Returns:

Dictionary containing:
  • ’inverse_transform’: patient to model space transform

  • ’forward_transform’: model to patient space transform

  • ’registered_template_model_surface’: Transformed model model

  • ’registered_template_labelmap’: Transformed model labelmap

Return type:

dict

transform_model(base_model=None)[source]

Apply registration transforms to the model.

Transforms the model through all registration stages.

Parameters:

base_model (Optional[DataSet]) – Base model for generating the new model. If None, the template model is used.

Returns:

Registered model

Return type:

pv.DataSet

run_workflow(use_icon_registration_refinement=False)[source]

Execute the complete multi-stage registration workflow.

Runs registration stages in sequence:

  1. ICP alignment (RegisterModelsICP)

  2. PCA registration (PCA data was provided)

  3. Mask-to-mask deformable registration (RegisterModelsDistanceMaps)

  4. Optional mask-to-image refinement (Icon); requires template labelmap and IDs

    set via set_use_mask_to_image_registration(True, …).

Parameters:

use_icon_registration_refinement (bool) – Whether to include icon registration refinement stage. Default: False

Return type:

dict

Returns:

dict with registered_template_model and registered_template_model_surface

import itk
import pyvista as pv

from physiomotion4d import WorkflowFitStatisticalModelToPatient

workflow = WorkflowFitStatisticalModelToPatient(
    template_model=pv.read("template_heart.vtu"),
    patient_models=[pv.read("lv.vtp"), pv.read("rv.vtp")],
    patient_image=itk.imread("patient_ct.nii.gz"),
)

result = workflow.run_workflow()

High-Resolution 4D CT Reconstruction

class physiomotion4d.WorkflowReconstructHighres4DCT(time_series_images, fixed_image, reference_frame=0, register_reference=False, registration_method='ants_icon', log_level=20)[source]

Bases: PhysioMotion4DBase

Reconstruct high-resolution 4D CT from time series and reference image.

This class implements a workflow for reconstructing high-resolution dynamic CT images by registering low-resolution time-series images to a high-resolution reference image using combined ANTS+ICON registration.

Registration Pipeline:
  1. Time Series Registration: Register each time-series image to the high-resolution reference using RegisterTimeSeriesImages with ants_icon method

  2. Reconstruction: Apply inverse transforms to reconstruct high-resolution time series

  3. Optional Upsampling: Resample to isotropic high resolution

Input Requirements:
  • time_series_images: Ordered list of 3D images (typically lower resolution)

  • fixed_image: High-resolution reference image

  • All images should be in the same anatomical coordinate system

time_series_images

Ordered list of time-series images

Type:

list[itk.Image]

fixed_image

High-resolution reference image

Type:

itk.Image

reference_frame

Index of reference frame in time series

Type:

int

register_reference

Whether to register reference frame

Type:

bool

prior_weight

Weight for temporal smoothing (0.0-1.0)

Type:

float

upsample_to_fixed_resolution

Whether to upsample reconstruction

Type:

bool

registration_method

Registration method (‘ants’, ‘icon’, or ‘ants_icon’)

Type:

str

number_of_iterations

Iterations for registration

registrar

Internal registration object

Type:

RegisterTimeSeriesImages

forward_transforms

Forward transforms (moving → fixed)

Type:

list[itk.Transform]

inverse_transforms

Inverse transforms (fixed → moving)

Type:

list[itk.Transform]

losses

Registration loss values

Type:

list[float]

reconstructed_images

Reconstructed high-resolution images

Type:

list[itk.Image]

Example

>>> # Initialize workflow with data
>>> workflow = WorkflowReconstructHighres4DCT(
...     time_series_images=lowres_images,
...     fixed_image=highres_reference,
...     reference_frame=3,
...     registration_method='ants_icon',
... )
>>>
>>> # Configure registration parameters
>>> workflow.set_number_of_iterations_ants([30, 15, 7])
>>> workflow.set_number_of_iterations_icon(20)
>>> workflow.set_prior_weight(0.5)
>>>
>>> # Run complete workflow
>>> result = workflow.run_workflow(upsample_to_fixed_resolution=True)
>>>
>>> # Access results
>>> reconstructed = result['reconstructed_images']
>>> transforms = result['forward_transforms']
>>> losses = result['losses']
__init__(time_series_images, fixed_image, reference_frame=0, register_reference=False, registration_method='ants_icon', log_level=20)[source]

Initialize the high-resolution 4D CT reconstruction workflow.

Parameters:
  • time_series_images (list[itk.Image]) – Ordered list of 3D time-series images to be registered and reconstructed

  • fixed_image (itk.Image) – High-resolution 3D reference image

  • reference_frame (int, optional) – Index of the reference frame in the time series. Registration proceeds bidirectionally from this frame. Default: 0

  • register_reference (bool, optional) – If True, register the reference frame to the fixed image. If False, use identity transform for reference. Default: False

  • registration_method (str, optional) – Registration method to use. Options: ‘ants’, ‘icon’, or ‘ants_icon’. Default: ‘ants_icon’

  • log_level (int | str) – Logging level (logging.DEBUG, logging.INFO, etc.). Default: logging.INFO

Raises:
set_number_of_iterations_ants(number_of_iterations_ants)[source]

Set the number of iterations for ANTs registration.

Parameters:

number_of_iterations_ants (list[int]) – List of iterations for ANTs multi-resolution (e.g., [30, 15, 7, 3] for four resolution levels)

Return type:

None

set_number_of_iterations_icon(number_of_iterations_icon)[source]

Set the number of iterations for ICON registration.

Parameters:

number_of_iterations_icon (int) – Number of fine-tuning steps for ICON

Return type:

None

set_prior_weight(prior_weight)[source]

Set the weight for temporal smoothing with prior transforms.

Parameters:

prior_weight (float) – Weight (0.0 to 1.0) for using the prior image’s transform to initialize the next registration. 0.0 means no prior information is used (each registration starts from identity). Higher values provide more temporal smoothness but may propagate errors.

Raises:

ValueError – If prior_weight not in [0.0, 1.0]

Return type:

None

set_modality(modality)[source]

Set the imaging modality for registration optimization.

Parameters:

modality (str) – The imaging modality (e.g., ‘ct’, ‘mri’)

Return type:

None

set_mask_dilation(mask_dilation_mm)[source]

Set the dilation of the fixed and moving image masks.

Parameters:

mask_dilation_mm (float) – The dilation in millimeters

Return type:

None

set_fixed_mask(fixed_mask)[source]

Set a binary mask for the fixed image region of interest.

Parameters:

fixed_mask (itk.Image) – Binary mask defining ROI in fixed image

Return type:

None

set_moving_masks(moving_masks)[source]

Set binary masks for the moving images.

Parameters:

moving_masks (list[itk.Image] | None) – List of binary masks, one for each moving image. If None, no masks are used. Must have same length as time_series_images if provided.

Raises:

ValueError – If moving_masks length doesn’t match time_series_images

Return type:

None

register_time_series()[source]

Register time series images to the fixed image.

Performs sequential registration of all time-series images to the high-resolution reference image using the configured parameters.

Returns:

Dictionary containing:
  • ’forward_transforms’ (list[itk.Transform]): Transforms from moving to fixed space (warps moving → fixed)

  • ’inverse_transforms’ (list[itk.Transform]): Transforms from fixed to moving space (warps fixed → moving)

  • ’losses’ (list[float]): Registration loss value for each image

Return type:

dict

Raises:

RuntimeError – If registration fails

reconstruct_time_series(upsample_to_fixed_resolution=False)[source]

Reconstruct high-resolution time series using inverse transforms.

Applies the inverse transforms from registration to reconstruct each time-series image in the high-resolution fixed image space.

Parameters:

upsample_to_fixed_resolution (bool, optional) – If True, reconstructed images will be upsampled to isotropic resolution (mean of fixed image’s X and Y spacing) while maintaining their original origin and direction. Default: False

Returns:

Dictionary containing:
  • ’reconstructed_images’ (list[itk.Image]): Reconstructed high-resolution time-series images

Return type:

dict

Raises:
  • RuntimeError – If reconstruction fails

  • ValueError – If inverse_transforms is not set (call register_time_series first)

run_workflow(upsample_to_fixed_resolution=False)[source]

Execute the complete high-resolution 4D CT reconstruction workflow.

Runs the full pipeline: 1. Register time series to high-resolution reference 2. Reconstruct high-resolution time series using inverse transforms

Parameters:

upsample_to_fixed_resolution (bool, optional) – If True, reconstructed images will be upsampled to isotropic high resolution. Default: False

Returns:

Dictionary containing all results:
  • ’forward_transforms’ (list[itk.Transform]): Registration transforms

  • ’inverse_transforms’ (list[itk.Transform]): Inverse transforms

  • ’losses’ (list[float]): Registration loss values

  • ’reconstructed_images’ (list[itk.Image]): Reconstructed high-res images

Return type:

dict

Raises:

RuntimeError – If any stage of the workflow fails

import itk

from physiomotion4d import WorkflowReconstructHighres4DCT

time_series_images = [itk.imread(f"phase_{idx:02d}.mha") for idx in range(10)]
workflow = WorkflowReconstructHighres4DCT(
    time_series_images=time_series_images,
    fixed_image=time_series_images[0],
    reference_frame=0,
    registration_method="ants",
)

result = workflow.run_workflow(upsample_to_fixed_resolution=True)

See Also