Skip to content

API Reference

Loading

mrsimtracks.io.load_flow(path: str | os.PathLike[str] | Iterable[str | os.PathLike[str]], active_key: str = 'velocity', subsamp: int = 1, only_active_key: bool = True, pbar: bool = False, dt: float | None = None, precision: str = 'f64', time_interp: str = 'linear', conform_mesh: bool = True, mesh_mode: str = 'auto') -> Flow

Load a time-resolved flow into one source-independent representation.

Supported sources are a single .vtu containing name_NNNNN point fields, a .pvd collection, a directory of per-frame .vtu files, or an explicit iterable of .vtu paths. Separate-file series are checked frame by frame and classified as static, moving-node, or topology-changing unless mesh_mode declares the layout. Identical topology and coordinates are stored once; only changed arrays are decoded after the first full mesh load.

Parameters:

Name Type Description Default
path str | PathLike[str] | Iterable[str | PathLike[str]]

A VTU/PVD path, directory, or iterable of VTU paths.

required
active_key str

Three-component point-data field name. Matching is case-insensitive; a single VTU expects active_key_NNNNN arrays.

'velocity'
subsamp int

Keep every Nth time frame for every source layout.

1
only_active_key bool

Skip unrelated point arrays in a single multi-field VTU.

True
pbar bool

Show load progress.

False
dt float | None

Optional multiplier for PVD, directory, or file-list time labels.

None
precision str

Working field precision, "f64" or "f32".

'f64'
time_interp str

"linear" or uniform-grid "cubic" interpolation.

'linear'
conform_mesh bool

Split supported non-tetrahedral cells and remove degenerate tetrahedra before building the fast sampler.

True
mesh_mode str

"auto" to classify every frame, "static" to reuse the first mesh while checking midpoint coordinates and topology, "moving" to reuse the first connectivity while loading coordinates per frame and checking midpoint topology, or "changing_topology" to load geometry per frame. The aliases "moving-node" and "moving_node" are accepted.

'auto'

Returns:

Name Type Description
Flow Flow

Unified flow object used by tracking, reseeding, and imaging.

mrsimtracks.ale.load_ale_flow(path: str | os.PathLike[str] | Iterable[str | os.PathLike[str]], velocity_key: str = 'Velocity', displacement_key: str = 'Displacement', mesh_velocity_key: str = 'Mesh_velocity', *, subsamp: int = 1, pbar: bool = False, dt: float | None = None, precision: str = 'f64', conform_mesh: bool = True, velocity_scale: float = 1.0) -> ALEFlow

Load ALE velocity, mesh velocity, and displacement on a static mesh.

path may be a PVD collection, a directory of VTUs, or an explicit VTU path iterable. Every selected frame must have identical node coordinates and cell connectivity. All three requested point fields are loaded eagerly.

Parameters:

Name Type Description Default
path str | PathLike[str] | Iterable[str | PathLike[str]]

PVD path, VTU directory, or explicit VTU path iterable.

required
velocity_key str

Three-component physical velocity point field.

'Velocity'
displacement_key str

Three-component nodal displacement point field.

'Displacement'
mesh_velocity_key str

Three-component mesh-velocity point field.

'Mesh_velocity'
subsamp int

Keep every Nth frame.

1
pbar bool

Show load progress.

False
dt float | None

Optional multiplier for PVD, directory, or file-list time labels.

None
precision str

Stored field precision, "f64" or "f32".

'f64'
conform_mesh bool

Split supported non-tetrahedral cells and remove degenerate tetrahedra on the shared reference mesh.

True
velocity_scale float

Multiplier converting both velocity fields to reference mesh spatial units per second. Displacement is not scaled because it must already use the same units as the reference coordinates.

1.0

Returns:

Name Type Description
ALEFlow ALEFlow

Static reference mesh with time-resolved velocity and

ALEFlow

displacement fields.

mrsimtracks.motion.load_mesh_motion(path: str | os.PathLike[str] | Iterable[str | os.PathLike[str]], displacement_key: str | None = None, *, subsamp: int = 1, pbar: bool = False, dt: float | None = None, precision: str = 'f64', periodic: bool = True) -> MeshMotion

Load fixed-topology mesh motion from coordinates or nodal displacement.

Parameters:

Name Type Description Default
path str | PathLike[str] | Iterable[str | PathLike[str]]

A VTU/PVD path, directory, or explicit VTU path iterable.

required
displacement_key str | None

Three-component nodal displacement field. When omitted, every VTU frame's point coordinates are treated as the absolute node positions.

None
subsamp int

Keep every Nth frame.

1
pbar bool

Show load progress.

False
dt float | None

Optional multiplier for PVD, directory, or file-list time labels.

None
precision str

Stored node-position precision, "f64" or "f32".

'f64'
periodic bool

Wrap evaluation times over the loaded motion duration.

True

Returns:

Name Type Description
MeshMotion MeshMotion

Fixed-topology deformation ready for material seeding.

mrsimtracks.motion.MeshMotion

Fixed-topology mesh deformation represented by absolute node positions.

mesh(frame=0)

Return one mesh frame with the shared topology.

point_cloud(particles, time)

Return material-particle positions as a PyVista point cloud.

positions(particles, time)

Evaluate material-particle positions at one time.

seed(n_particles, rng=None)

Uniformly seed exactly n_particles material points by volume.

Hexahedra, wedges, and other supported volume cells are split once when the motion is loaded. Particles retain the resulting tetrahedron id and barycentric weights for every subsequent frame.

trajectory(particles, times=None, output_path=None)

Evaluate material positions in memory or stream them to HDF5.

mrsimtracks.motion.MaterialPoints dataclass

Fixed cell-local coordinates for particles attached to a mesh.

mrsimtracks.motion.MaterialTrajectory

In-memory or HDF5-backed fixed-topology material trajectories.

open(path) classmethod

Open a streamed material trajectory without loading positions.

Tracking

mrsimtracks.core.track(flow, seeds=None, dt=0.001, tmax=None, reseeder=None, inlet=None, method='RK4', pbar=True, rng=None, output_path=None, return_metrics=False, wall_slip=None, time_subsample=1)

Track particles through a loaded flow field.

The returned trajectory starts with the initial seeds at t=0 and stores each stepped position at dt, 2*dt, and so on. RK4 particles are recycled at the end-of-step time when any stage query (k1 through k4) is outside the mesh after the sampler's point-location checks.

Parameters:

Name Type Description Default
flow object

Loaded flow field from :func:mrsimtracks.load_flow or :func:mrsimtracks.load_ale_flow.

required
seeds ndarray | PolyData

Initial particle positions as an (n, 3) array or pyvista.PolyData.

None
dt float

Tracking time step in seconds.

0.001
tmax float | None

Total tracking duration. Defaults to one flow period.

None
reseeder BoundaryReseeder | None

Boundary reseeder used to recycle out-of-bounds particles. If omitted, inlet must provide static reset points.

None
inlet ndarray | None

Static reset points used when reseeder is omitted.

None
method str

Integration method, either "RK4" or "Euler".

'RK4'
pbar bool

Show a progress bar.

True
rng Generator | None

Optional generator for deterministic reset draws.

None
output_path str | Path | None

Optional HDF5 path. When provided, positions/reset flags are streamed to disk and the returned result is file-backed until arrays are accessed.

None
time_subsample int

With output_path, save every Nth integration state. Reset flags are accumulated over each saved interval.

1
return_metrics bool

When True, return (result, metrics) with loop timing metrics.

False
wall_slip WallSlip | None

Optional near-wall no-penetration projection (see :class:mrsimtracks.WallSlip) that strips the into-wall velocity component near walls so particles slide instead of being deposited and trapped.

None

Returns:

Type Description
Union[TrackingResult, tuple]

TrackingResult by default, or (TrackingResult, metrics) when return_metrics=True.

mrsimtracks.parallel.track_parallel(path, seeds, dt=0.001, tmax=None, caps=None, inlet=None, n_workers=3, active_key='velocity', method='RK4', subsamp=1, only_active_key=True, pbar=True, rng=None, return_metrics=False, precision='f64', time_interp='linear', conform_mesh=True, mesh_mode='auto', wall_slip=False, wall_slip_band=0.02)

Track particles in parallel, with each worker reloading the flow field.

Parameters:

Name Type Description Default
path str | Path | iterable

A .vtu or .pvd path, a directory of per-frame VTUs, or an explicit VTU path iterable.

required
seeds ndarray

Initial particle positions as an (n, 3) array.

required
dt float

Tracking time step in seconds.

0.001
tmax float | None

Total tracking duration. Defaults to one flow period.

None
caps str | Path | list | None

Cap surface path(s) used to build a BoundaryReseeder per worker.

None
inlet ndarray | None

Static reset points used when caps is omitted.

None
n_workers int

Number of particle batches/processes.

3
active_key str

Velocity array prefix in the flow files.

'velocity'
method str

Integration method, either "RK4" or "Euler".

'RK4'
subsamp int

Keep every Nth frame when loading .pvd data.

1
only_active_key bool

Load only velocity arrays for .vtu inputs.

True
pbar bool

Show a progress bar for the first worker.

True
rng Generator | None

Optional generator for deterministic batching and reset draws.

None
return_metrics bool

When True, return (result, metrics).

False
precision str

Working precision for the sampling/advection math, "f64" (default) or "f32" (single, faster but less accurate).

'f64'
time_interp str

Temporal interpolation between frames, "linear" (default) or "cubic" (Catmull-Rom; requires uniform spacing).

'linear'
conform_mesh bool

Condition the mesh to clean all-tet at load (split non-tet cells, drop degenerate cells). Default True.

True
mesh_mode str

Mesh classification policy passed to load_flow. Default "auto".

'auto'
wall_slip bool

Apply the near-wall no-penetration projection (built per worker from caps). Default False.

False
wall_slip_band float

Slip band as a fraction of vessel diameter when wall_slip is enabled. Default 0.02.

0.02

Returns:

Type Description
Union[TrackingResult, tuple]

TrackingResult by default, or (TrackingResult, metrics) when return_metrics=True.

mrsimtracks.core.TrackingResult

Particle trajectories and reset flags from a tracking run.

Parameters:

Name Type Description Default
positions ndarray | None

In-memory particle positions with shape (n_states, n_particles, 3). State zero contains the initial seeds; subsequent states are separated by dt.

None
reset ndarray | None

In-memory reset flags with shape (n_states, n_particles). State zero is always false. For RK4, subsequent flags are set when any of the four stage queries is outside the flow mesh.

None
dt float | None

Tracking time step in seconds.

None
path str | Path | None

HDF5 file path for a file-backed result.

None
shape tuple[int, int, int] | None

Position dataset shape for file-backed results.

None
metrics dict | None

Optional timing/throughput metrics returned by tracking.

None

open(path) classmethod

Open a file-backed result without loading positions into memory.

save(path, time_subsample=1)

Write positions/reset/dt to HDF5, accumulating skipped resets.

Periodic Mapping

mrsimtracks.mapping.periodic_mapping(initial_positions, final_positions) -> np.ndarray

Map each initial particle location to its nearest final particle.

The result is a destination-to-source map for KomaMRI FlowPath motion: particle i receives the state of particle mapping[i] at the cycle boundary. Indices are 1-based for direct use as Koma's cycle_map. Neighbors use ordinary Euclidean distance without spatial boundary wrapping. Equidistant ties follow scipy.spatial.cKDTree selection.

Parameters:

Name Type Description Default
initial_positions array - like

Initial coordinates with shape (n, 3).

required
final_positions array - like

Final coordinates with shape (n, 3).

required

Returns:

Type Description
ndarray

np.ndarray: One-based nearest-neighbor indices with shape (n,) and dtype int64. Multiple initial positions may map to the same final particle.

Velocity Images

mrsimtracks.imaging.sample_velocity_image(flow: object, *, fov: object = None, resolution: float | tuple[float, float, float], temporal_spacing: float, temporal_width: float, grid_subsampling: int = 1, start_time: float = 0.0, reorder_by_extent: bool = False) -> VelocityImage

Sample a CFD flow onto a time-resolved Cartesian velocity image.

Parameters:

Name Type Description Default
flow object

Flow returned by :func:mrsimtracks.load_flow.

required
fov object

FOV in the selected output axis order: native (x,y,z) by default, or extent order when reorder_by_extent=True. Pass three widths centered on the mesh bounding-box center, three explicit (minimum, maximum) pairs, or None for the mesh bounds.

None
resolution float | tuple[float, float, float]

Requested voxel size in mesh spatial units, as one isotropic value or three values in the selected output axis order. The FOV is tiled exactly with voxel sizes no larger than requested.

required
temporal_spacing float

Spacing between output time points in seconds.

required
temporal_width float

Boxcar averaging width in seconds. Zero performs linear interpolation at each exact output time.

required
grid_subsampling int

Number of regular sub-samples per voxel axis. A value of two averages eight samples per nominal voxel.

1
start_time float

First output time in seconds. Output continues periodically at temporal_spacing until the end of the CFD period.

0.0
reorder_by_extent bool

When True, reorder spatial axes and velocity components by descending mesh extent. The default False preserves native tracking order (x,y,z). Neither mode shifts the origin.

False

Returns:

Name Type Description
VelocityImage VelocityImage

Dense (time, x, y, z, component) velocity and spatial occupancy arrays in the same coordinate convention as track.

mrsimtracks.imaging.VelocityImage dataclass

Dense velocity image sampled from a CFD flow.

The coordinate origin is never shifted. Spatial axes and vector components are native (x,y,z) by default or carry the same optional extent-based permutation recorded in axis_permutation. occupancy is the fraction of spatial sub-samples inside the CFD domain.

load(path) classmethod

Load an HDF5 image saved by :meth:save into dense memory.

save(path, sparse=True)

Save to HDF5, sparsifying the fixed spatial support by default.

Reseeding

mrsimtracks.reseeding.BoundaryReseeder

Flux-weighted boundary reseeder for particles that leave the domain.

The reseeder samples currently inflowing cap faces using per-face weights max(-v . n, 0) * area. This handles backflow and caps that are partly inflow and partly outflow at the same timestep.

Parameters:

Name Type Description Default
caps PolyData | str | Path | list

A cap surface with a per-cell region_id array, a path to such a file, or a list of cap surface paths/meshes. A list is interpreted as one cap per item.

required
flow object

Loaded flow object returned by mrsimtracks.load_flow.

required
rng Generator | None

Optional generator for repeatable reseeding.

None
region_key str

Cell-data array name used to identify cap regions.

'region_id'
inward_eps float | None

Minimum inward offset for reseeded points.

None
dt float | None

Tracking time step. When provided, reseeded points are spread over a thin inward volume instead of a single plane.

None
verify bool

Check reseeded points with the mesh locator and fall back to known-valid face sample points if needed.

True

flux_waveform()

Net signed flux per cap over the cycle (positive = outflow).

Returns (frame_times, flux[nframes, n_caps]). Summing across caps per frame should be ~0 by mass conservation -- a useful correctness check.

reseed(n, t)

Return (n, 3) seed points just inside currently-inflow cap faces.

mrsimtracks.reseeding.ALEBoundaryReseeder

Bases: BoundaryReseeder

Flux-weighted reseeding on deforming ALE boundary caps.

Cap vertices must correspond to nodes of the ALE reference mesh. At each reseeding time the cap is displaced, triangle geometry is recomputed, and face probability is proportional to area * max(-(Velocity - Mesh_velocity) . outward_normal, 0).

reseed(n, t)

Return ALE-aware seed locations, preserving the public points API.

reseed_with_cells(n, t)

Return seed locations and their flow-topology cell IDs.

Wall Slip

mrsimtracks.wall_slip.WallSlip

Near-wall no-penetration projection sized as a fraction of vessel diameter.

Parameters:

Name Type Description Default
flow object

Loaded flow with an all-tetrahedral mesh (load with the default conform_mesh=True); uses its fast sampler's geometry.

required
caps list | None

Open-boundary cap surfaces (paths or meshes) to exclude from the wall set so inflow/outflow is not blocked. If None, every domain-boundary face is treated as a wall.

None
band_frac float

Band thickness as a fraction of the vessel hydraulic diameter D_h = 4 V / A_wall. Default 0.02 (2%).

0.02

Attributes:

Name Type Description
d_hydraulic float

Estimated vessel diameter.

band float

Absolute band thickness used (band_frac * d_hydraulic).

apply(positions, velocity)

Remove the into-wall velocity for particles within the wall band.

velocity is modified in place and returned. positions is the current particle position used to find the nearest wall face.

Seeding

mrsimtracks.seeding.seed_mesh(mesh, npoints, rng=None)

Seed points inside the full mesh bounds.

Parameters:

Name Type Description Default
mesh DataSet

PyVista mesh defining the flow domain.

required
npoints int

Target number of seed points. The stochastic refinement can return fewer points when the domain is sparse or normalization rejects samples.

required
rng Generator | None

Optional generator for repeatable seeding.

None

Returns:

Type Description
ndarray

Array of seed points with shape (n, 3).

mrsimtracks.seeding.seed_region(mesh, npoints, bounds, normalization=None, rng=None)

Seed points inside a bounded region of a mesh.

Parameters:

Name Type Description Default
mesh DataSet

PyVista mesh defining the flow domain.

required
npoints int

Target number of seed points.

required
bounds Sequence[float]

Region bounds in PyVista order (xmin, xmax, ymin, ymax, zmin, zmax).

required
normalization str | None

Optional point-data array name used for stochastic density weighting.

None
rng Generator | None

Optional generator for repeatable seeding.

None

Returns:

Type Description
ndarray

Array of seed points with shape (n, 3).