The Per-Subject Manifest
The manifest is the contract between your data and the training stack. It is the only thing you must produce to train on your own subjects: one JSON file per subject, naming a fitted reference mesh, that subject’s PCA shape parameters, the point-data array holding the training targets, and one entry per phase.
{
"subject_id": "Case1Pack",
"fitted_reference_mesh": "Case1Pack_ssm_surface.vtp",
"pca_coefficients": "Case1Pack_ssm_pca_coefficients.json",
"target_array": "displacement",
"phases": [
{"mesh": "Case1Pack_T00_ssm_surface_target.vtp", "stage": 0.0},
{"mesh": "Case1Pack_T50_ssm_surface_target.vtp", "stage": 0.5}
]
}
Relative paths resolve against the manifest’s own directory.
Targets are read verbatim
The stack never derives targets from geometry. Whatever array
target_array names is what the network learns to predict, and its width
sets the network’s output size - three columns for a displacement, one for a
scalar field, any number for something else. Tutorial 9 writes
phase.points - reference.points into that array, which is what makes its
model a motion model; write something else and the same code trains on it.
Every phase mesh must share the template’s point count and ordering, and
stage is the caller’s own normalization of where the phase sits in the
cycle - the workflow never parses filenames.
Meshes may be surfaces (.vtp) or volumes (.vtu); the template mesh
decides which domain the model lives on.
Reference
ProcessPhysicsNemo is re-exported from the top-level package;
SubjectManifest and PhaseEntry are not - import those by module:
from monai_physio import ProcessPhysicsNemo
from monai_physio.process_physicsnemo import SubjectManifest
manifest = ProcessPhysicsNemo.parse_manifest(manifest_path)
- class monai_physio.process_physicsnemo.SubjectManifest(subject_id, fitted_reference_mesh, pca_coefficients, target_array, phases)[source]
A single subject’s training/inference inputs.
- subject_id
Identifier used for output naming.
- fitted_reference_mesh
The subject’s SSM surface as fitted to that subject by
monai_physio.WorkflowFitStatisticalModelToPatient(.vtpsurface or.vtuvolume) — shape parameters and a deformable registration, never shape parameters alone. It supplies the point positions the targets are defined at; the stack never derives targets from it.
- pca_coefficients
JSON file holding the subject’s PCA shape-parameter vector (a flat list of floats).
- target_array
Name of the point-data array holding the target values in every phase mesh.
- phases
One
PhaseEntryper phase (at least one).
- __init__(subject_id, fitted_reference_mesh, pca_coefficients, target_array, phases)
Supporting helpers
- class monai_physio.process_physicsnemo.ProcessPhysicsNemo[source]
Namespace of stateless helpers shared by the PhysicsNeMo workflows.
Every member is a
@staticmethod: there is no instance state, so this is a grouping rather than an object to construct. Wrapping does not change when a method’s own localimport torch/import torch_geometricruns - only at call time - soimport monai_physiostays as lightweight as it was when these were bare functions.- static import_meshgraphnet()[source]
Import PhysicsNeMo’s
MeshGraphNet, reporting install faults clearly.PhysicsNeMo builds MeshGraphNet on
torch_scatter, a compiled extension whose prebuilt wheels are published only for specific(torch, CUDA, Python, platform)combinations. A wheel built against a different torch than the installed one loads as an opaqueOSError: Could not load this library: ..._scatter_cuda.pyd, which names neither torch_scatter nor the version mismatch that caused it. Translate that into a message that does.- Return type:
type[MeshGraphNet]
- Returns:
The
physicsnemo.models.meshgraphnet.MeshGraphNetclass.- Raises:
ImportError – PhysicsNeMo or PyTorch Geometric could not be imported, or the installed
torch_scatterbinary does not match the installed torch.
- static parse_manifest(manifest_path)[source]
Parse a per-subject JSON manifest.
Paths inside the manifest are resolved relative to the manifest’s own directory unless already absolute. Every phase must declare a
stage.- Parameters:
manifest_path (
Path) – Path to the subject manifest JSON file.- Return type:
- Returns:
The parsed
SubjectManifest.- Raises:
FileNotFoundError – If the manifest file does not exist.
ValueError – If required fields are missing, a phase lacks
stage, or no phases are listed.
- static load_pca_coefficients(path)[source]
Load a PCA shape-parameter vector saved as a JSON list of floats.
- Return type:
- static load_target_array(path, array_name)[source]
Read one mesh’s target values out of its point data.
- Parameters:
- Return type:
- Returns:
(n_points, n_target)float32 targets; a scalar array is returned as(n_points, 1).- Raises:
KeyError – If
array_nameis not among the mesh’s point-data arrays.
- static build_node_features(mean_coords_norm, pca_norm, stage)[source]
Assemble per-vertex node features
[coords_norm, pca_norm, stage].- Parameters:
- Return type:
- Returns:
(n_points, 3 + n_pca + 1)float32 feature array.
- static mesh_to_edge_index(mesh)[source]
Build an undirected
edge_indexfrom a surface or volumetric mesh.- Parameters:
mesh (
DataSet) – Template mesh whose cells encode the topology.pv.PolyDatais read straight from its triangulated faces; any other dataset (a volumetricpv.UnstructuredGrid, for example) goes throughextract_all_edges.- Return type:
- Returns:
(2, n_edges)long tensor of undirected edges indexing the mesh’s own points.- Raises:
ValueError – If edge extraction renumbers the points, which would break the correspondence between node features and graph nodes.
- static compute_edge_features(coords, edge_index)[source]
Build
(n_edges, 4)edge features[rel_x, rel_y, rel_z, distance].- Return type:
- static distributed_context()[source]
Initialize PhysicsNeMo’s
DistributedManagerand read it back.DistributedManager.initializepicks uptorchrun, SLURM or OpenMPI environments and falls back to a single process when it finds none, so this is safe to call from any entry point. Initialization is done once per process; calling this again returns the same context.- Raises:
ImportError – If the process was launched as one of several and PhysicsNeMo is not installed. Raised before anything is imported or written, so the caller has not yet created an output directory.
- Return type:
DistributedContext
- static unwrap_model(model)[source]
Return the bare module inside any
torch.compile/ DDP wrappers.Both wrappers can be applied, in either order, so peel until neither attribute is left rather than checking for one of them.
- Return type:
- class monai_physio.process_physicsnemo.PhaseSampleDataset(samples, mean_coords_norm, target_array, target_scale, cache_max_samples=0)[source]
Lazy provider of
(node_features, normalized_target)samples.One item is one
(subject, phase)pair. Node features are rebuilt on access from the shared normalized template coordinates plus the subject’s normalized PCA parameters and the phase stage (cheap). Only the phase target arrays are read from disk, and those are held in a bounded LRU cache so an arbitrarily large training set streams from disk while a small set stays resident. Targets are returned as stored - the dataset never derives them from geometry.- Parameters:
samples (
list[_Sample]) – Flat list of_Sample(built by the workflow).mean_coords_norm (
ndarray) –(n_points, 3)normalized template coordinates.target_array (
str) – Point-data array name holding the targets.target_scale (
float) – Target normalization factor (targets are divided by it so they land in~[-1, 1]).cache_max_samples (
int) – Maximum decoded target arrays to cache.0means unbounded (all-in-RAM, fastest); a small value forces disk streaming.