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

These live in physiotwin4d.physicsnemo_tools, which is not re-exported from the top-level package — import it by module:

from physiotwin4d.physicsnemo_tools import SubjectManifest, parse_manifest
class physiotwin4d.physicsnemo_tools.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 physiotwin4d.WorkflowFitStatisticalModelToPatient (.vtp surface or .vtu volume) — 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 PhaseEntry per phase (at least one).

__init__(subject_id, fitted_reference_mesh, pca_coefficients, target_array, phases)
class physiotwin4d.physicsnemo_tools.PhaseEntry(mesh, stage)[source]

One phase mesh carrying the target array, and its normalized stage.

__init__(mesh, stage)
physiotwin4d.physicsnemo_tools.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:

SubjectManifest

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.

physiotwin4d.physicsnemo_tools.load_target_array(path, array_name)[source]

Read one mesh’s target values out of its point data.

Parameters:
  • path (Path) – Mesh holding the targets (.vtp surface or .vtu volume).

  • array_name (str) – Point-data array name declared by the manifest.

Return type:

ndarray

Returns:

(n_points, n_target) float32 targets; a scalar array is returned as (n_points, 1).

Raises:

KeyError – If array_name is not among the mesh’s point-data arrays.

physiotwin4d.physicsnemo_tools.load_pca_coefficients(path)[source]

Load a PCA shape-parameter vector saved as a JSON list of floats.

Return type:

ndarray

Supporting helpers

physiotwin4d.physicsnemo_tools.build_node_features(mean_coords_norm, pca_norm, stage)[source]

Assemble per-vertex node features [coords_norm, pca_norm, stage].

Parameters:
  • mean_coords_norm (ndarray) – (n_points, 3) normalized mean-shape coordinates (identical for every subject/phase).

  • pca_norm (ndarray) – (n_pca,) normalized PCA shape parameters for the subject.

  • stage (float) – Normalized cardiac stage (RR-interval fraction) for the phase.

Return type:

ndarray

Returns:

(n_points, 3 + n_pca + 1) float32 feature array.

physiotwin4d.physicsnemo_tools.mesh_to_edge_index(mesh)[source]

Build an undirected edge_index from a surface or volumetric mesh.

Parameters:

mesh (DataSet) – Template mesh whose cells encode the topology. pv.PolyData is read straight from its triangulated faces; any other dataset (a volumetric pv.UnstructuredGrid, for example) goes through extract_all_edges.

Return type:

Tensor

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.

physiotwin4d.physicsnemo_tools.compute_edge_features(coords, edge_index)[source]

Build (n_edges, 4) edge features [rel_x, rel_y, rel_z, distance].

Return type:

Tensor

class physiotwin4d.physicsnemo_tools.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. 0 means unbounded (all-in-RAM, fastest); a small value forces disk streaming.

__init__(samples, mean_coords_norm, target_array, target_scale, cache_max_samples=0)[source]
property n_points: int

Vertices per sample (shared across all subjects).

property n_features: int

Node feature dimension 3 + n_pca + 1.

property n_target: int

Target width (columns of the stored target array).

property subject_ids: list[str]

Subject id of every sample, in dataset order.

A physics residual is measured against the subject’s own reference geometry rather than the shared template, so a training method that adds one needs to know which subject a batch row came from.

__getitem__(index)[source]

Return (node_features, normalized_target) for one sample.

Return type:

tuple[ndarray, ndarray]

See Also