Metadata-Version: 2.4
Name: mrsimtracks
Version: 0.1.0rc1
Summary: Generate CFD-derived particle trajectories for MR flow simulation.
Project-URL: Homepage, https://github.com/mcgrathcm/MRSimTracks
Project-URL: Repository, https://github.com/mcgrathcm/MRSimTracks
Project-URL: Issues, https://github.com/mcgrathcm/MRSimTracks/issues
Project-URL: Changelog, https://github.com/mcgrathcm/MRSimTracks/blob/main/CHANGELOG.md
Author-email: Charles McGrath <cmmcg@stanford.edu>
License-Expression: MIT
License-File: LICENSE
Keywords: cfd,flow-simulation,mr-simulation,mri,particle-tracking,pyvista,streamlines,vtk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.12
Requires-Dist: h5py>=3.16.0
Requires-Dist: joblib>=1.5.3
Requires-Dist: matplotlib>=3.11.0
Requires-Dist: numba>=0.65.1
Requires-Dist: numpy>=2.4.6
Requires-Dist: pyvista>=0.48.4
Requires-Dist: scipy>=1.17.1
Requires-Dist: tqdm>=4.68.2
Requires-Dist: vtk>=9.6.2
Description-Content-Type: text/markdown

# MRSimTracks

Generate CFD-derived particle trajectories for MR flow simulation.

MRSimTracks performs Lagrangian particle tracking in time-resolved (pulsatile)
CFD meshes. It operates on mesh velocity fields, not MR image data. It seeds
particles in a tetrahedral flow domain, advects them through a time-periodic
velocity field (RK4), and recycles out-of-bounds particles back to the inflow
boundaries with optional **backflow-aware** reseeding.

## Install

From GitHub:

```bash
pip install "mrsimtracks @ git+https://github.com/mcgrathcm/MRSimTracks.git"
```

For development from a clone:

```bash
uv sync          # installs the package (editable) and dependencies
```

The distribution name and Python import package are both `mrsimtracks`.

## Quick start

```python
import numpy as np

import mrsimtracks as mt
from mrsimtracks.seeding import seed_mesh

# 1. Load a time-resolved flow field (.vtu single-file series or .pvd collection)
flow = mt.load_flow("case.pvd", active_key="Velocity")

# 2. (optional) Backflow-aware inflow reseeder from labeled cap surfaces
reseeder = mt.BoundaryReseeder(["Inlet.vtp", "Outlet.vtp"], flow, dt=0.002)

# 3. Seed and track
seeds = seed_mesh(flow.active_mesh, 200_000, rng=np.random.default_rng(0))
result = mt.track(flow, seeds=seeds, dt=0.002, reseeder=reseeder)

# 4. Use / save
result.positions      # (n_steps, n_particles, 3)
result.reset          # (n_steps, n_particles) reseed flags
result.times          # (n_steps,)
result.save("tracks.h5")
```

For large single-process runs, write each timestep directly to HDF5 instead of
keeping all positions in RAM:

```python
result, metrics = mt.track(
    flow,
    seeds=seeds,
    dt=0.002,
    reseeder=reseeder,
    output_path="tracks.h5",
    return_metrics=True,
)

result.is_file_backed  # True until result.positions or result.reset is loaded
metrics["particle_steps_per_s"]
```

Run `example.py` for a complete version using the reduced fixture committed in
`tests/data/`. The full-cycle example flow file is tracked with Git LFS; see
`example/README.md`.

## Large runs (multiple processes)

Each worker reloads the field, so memory scales with `n_workers`:

```python
result = mt.track_parallel(
    "case.pvd", seeds=seeds, dt=0.002,
    caps=["Inlet.vtp", "Outlet.vtp"], active_key="Velocity",
    n_workers=3, subsamp=1,
)
```

## Key functions

| Function | Purpose |
|---|---|
| `load_flow(path, active_key=...)` | Load `.vtu` (one geometry, many time fields) or `.pvd` (series); auto-selects the memory-efficient reader. `subsamp=N` keeps every Nth frame. |
| `track(flow, seeds=..., dt=..., reseeder=...)` | Single-process tracking → `TrackingResult`. Use `output_path=...` for streamed HDF5 output and `return_metrics=True` for timing metrics. |
| `track_parallel(path, ..., caps=..., n_workers=...)` | Multi-process tracking → `TrackingResult`. |
| `BoundaryReseeder(caps, flow, dt=...)` | Flux-weighted, time-resolved inflow reseeder. `caps` = cap surface path(s) or a surface with a `region_id` cell array. |

## Reseeding notes

- The reseeder weights every cap face by `max(-v·n, 0)·area` at the nearest flow
  frame, so particles re-enter only through currently-inflow faces — handling
  backflow and partial inflow/outflow on a single cap.
- `BoundaryReseeder(..., dt=dt)` spreads new particles over a thin inflow
  *volume* (depth `~v_n·dt`) so successive reseeds overlap, keeping spatial
  density smooth (important for MR-style uniform-density use). Omit `dt` for
  plane seeding.
- `flux_waveform()` returns per-cap net flux over the cycle — a conservation /
  validation diagnostic (`Σ caps ≈ 0` for a well-resolved incompressible field).

## Performance

Sampling reuses a cell-tree locator built once, a temporal-coherence tet walk
(numba) seeded from each particle's previous cell, and fused walk+interpolation.
`benchmark.py` measures sampling and tracking throughput.

## Development

Normal CI runs against a reduced real-data fixture:

```bash
uv sync --group dev
uv run pytest -m "not large" --cov=mrsimtracks --cov-report=term-missing
```

Full-data validation uses the Git LFS example file and runs only for release
validation:

```bash
git lfs pull --include="example/CFD_velocity.vtu"
uv run pytest -m large
```

See `CONTRIBUTING.md` for the full development workflow.

## Data

The included CFD fixtures are documented separately in `DATA_LICENSE.md`.

## Documentation

Documentation is built with MkDocs:

```bash
uv sync --group docs
uv run --group docs mkdocs build --strict
```

The GitHub Pages site is deployed from `main`.

## Notes

- Flow meshes are assumed all-tetrahedral and static in time (the field varies,
  the geometry does not).
- `.pvd` loading stores one geometry plus one field per frame for static-mesh
  series, so long time series fit in a few GB instead of tens.

## License

MIT.
