Homepage#

TorchSim#

TorchSim is a differentiable MR signal simulator built on PyTorch, with closed-form signal models and a fused extended-phase-graph (EPG) state machine for pulse trains.

codecov Tests Lint License Documentation PyPi Ruff PythonVersion

What it provides#

  • Vectorized signal simulation over voxels/atoms on CPU and NVIDIA GPU.

  • Forward-mode Jacobians with respect to tissue properties and reverse-mode differentiation with respect to sequence parameters.

  • Closed-form models and an EPG state machine with relaxation, off-resonance, diffusion, flow, transmit variation, magnetization transfer and chemical exchange.

  • Parameter inference, model-based reconstruction and sequence-design tools written against the same simulator interface.

  • Pulseq and MRD sequence-description input, so the same sequence model can be used offline or driven from a scanner stream.

Installation#

Install the PyTorch build appropriate for your machine first, then TorchSim:

pip install torchsim

See the User Guide for CPU, CUDA, macOS and source-build details.

Basic usage#

The central public object is a Simulator. A shipped simulator fixes the sequence; simulate and jacobian evaluate it over the tissue you pass:

import numpy as np
from torchsim.simulators import MRFSimulator

flip = np.concatenate(
    (np.linspace(5.0, 60.0, 300), np.linspace(60.0, 2.0, 300), np.full(280, 2.0))
)
sequence = MRFSimulator(flip=flip, TR=10.0)

signal, jacobian = sequence.jacobian(
    ("T1", "T2"),
    T1=1000.0,
    T2=100.0,
)

Functional helpers such as torchsim.mrf_sim(...) remain convenient for one-off calls. The class interface is the canonical one for reusable models, parameter estimation, reconstruction, optimization, Pulseq input and scanner descriptions.

Implementing a sequence#

Subclass torchsim.model.Simulator. For a state-machine sequence you define:

  1. the event handlers that say how excitation, refocusing, inversion, saturation, readout and delay commands are interpreted; and

  2. layout(), which returns those operators in order for offline use.

An incoming Pulseq/MRD description already supplies the layout, so Simulator.from_description() replays its commands through the same handlers. That gives offline design and scanner-driven simulation one public sequence abstraction.

The executable Framework course walks through the complete pattern.

Development#

git clone git@github.com:pulserver/torchsim
cd torchsim
pip install -e ".[dev]"
pre-commit install

The install compiles the two C++ kernels, so it needs a C++17 compiler. CMake and Ninja arrive as build-time dependencies. pre-commit runs the same Ruff format/lint checks as CI.