Skip to main content

High-performance Bloch equation simulator for MRI

Project description

Bloch Equation Simulator for Python

A high-performance Python implementation of the Bloch equation solver originally developed by Brian Hargreaves at Stanford University. This package provides a fast C-based core with Python bindings, parallel processing support, and an interactive GUI for MRI pulse sequence simulation.

Features

  • High Performance: C implementation with Cython bindings maintains original speed
  • Parallel Processing: OpenMP support for multi-core acceleration
  • Interactive GUI: Real-time visualization and parameter adjustment
  • Flexible API: Easy-to-use Python interface for scripting
  • Comprehensive: Supports arbitrary RF pulses, gradient waveforms, and tissue parameters
  • Visualization: 3D magnetization vectors, time evolution plots, frequency spectra, and animation export

Installation

Prerequisites

  1. Python 3.7+
  2. C Compiler:
    • Linux: gcc (usually pre-installed)
    • macOS: Xcode Command Line Tools (xcode-select --install)
    • Windows: Visual Studio Build Tools
  3. OpenMP (optional but recommended):
    • Linux: Included with gcc
    • macOS: brew install libomp
    • Windows: Included with Visual Studio

Quick Setup

# Clone or download the repository
cd bloch_simulator

# Install dependencies
pip install -r requirements.txt

# Build the extension
python build.py

# Or manually:
python setup.py build_ext --inplace

Verification

Test the installation:

from bloch_simulator import BlochSimulator, TissueParameters

sim = BlochSimulator()
tissue = TissueParameters.gray_matter(3.0)
print(f"T1: {tissue.t1:.3f}s, T2: {tissue.t2:.3f}s")

Usage

1. GUI Application

Launch the interactive GUI:

python bloch_gui.py

Features:

  • Design RF pulses (rectangular, sinc, Gaussian)
  • Configure tissue parameters (T1, T2, proton density)
  • Select pulse sequences (spin echo, gradient echo, etc.)
  • Real-time 3D magnetization visualization
  • Signal analysis and frequency spectra

2. Python API

Basic Simulation

import numpy as np
from bloch_simulator import BlochSimulator, TissueParameters

# Create simulator
sim = BlochSimulator(use_parallel=True, num_threads=4)

# Define tissue parameters
tissue = TissueParameters(
    name="Gray Matter",
    t1=1.33,  # seconds
    t2=0.083  # seconds
)

# Create a simple 90-degree pulse
ntime = 100
dt = 1e-5  # 10 microseconds
time = np.arange(ntime) * dt

b1 = np.zeros(ntime, dtype=complex)
b1[0] = 0.0235  # 90-degree hard pulse

gradients = np.zeros((ntime, 3))  # No gradients

# Run simulation
result = sim.simulate(
    sequence=(b1, gradients, time),
    tissue=tissue,
    mode=2  # Time-resolved output
)

# Plot results
sim.plot_magnetization()

Spin Echo Sequence

from bloch_simulator import BlochSimulator, SpinEcho, TissueParameters

sim = BlochSimulator()

# Create spin echo sequence
sequence = SpinEcho(te=20e-3, tr=500e-3)  # 20ms TE, 500ms TR

# Simulate white matter
tissue = TissueParameters.white_matter(3.0)

# Run simulation with multiple frequencies (T2* effects)
frequencies = np.linspace(-50, 50, 11)  # Hz
result = sim.simulate(sequence, tissue, frequencies=frequencies)

# Access magnetization components
mx, my, mz = result['mx'], result['my'], result['mz']
signal = result['signal']

Custom Pulse Design

from bloch_simulator import design_rf_pulse

# Design a sinc pulse
b1, time = design_rf_pulse(
    pulse_type='sinc',
    duration=2e-3,      # 2 ms
    flip_angle=180,     # degrees
    time_bw_product=4,  # Time-bandwidth product
    npoints=200
)

# Apply phase
phase = np.pi/4  # 45 degrees
b1_phased = b1 * np.exp(1j * phase)

Parallel Simulation

# Simulate multiple positions and frequencies in parallel
positions = np.random.randn(100, 3) * 0.01  # Random positions in 1cm cube
frequencies = np.linspace(-200, 200, 41)     # 41 frequencies

result = sim.simulate(
    sequence=sequence,
    tissue=tissue,
    positions=positions,
    frequencies=frequencies,
    mode=0  # Endpoint only (faster)
)

# Result shape: (100 positions, 41 frequencies)
print(f"Signal shape: {result['signal'].shape}")

3. Sequence Library

Pre-defined sequences are available:

from bloch_simulator import SpinEcho, GradientEcho

# Spin Echo
se = SpinEcho(te=30e-3, tr=1.0)

# Gradient Echo  
gre = GradientEcho(te=5e-3, tr=10e-3, flip_angle=30)

# Compile to waveforms
b1, gradients, time = se.compile(dt=1e-6)

4. Tissue Parameter Library

Common tissues at different field strengths:

from bloch_simulator import TissueParameters

# 3T parameters
gm = TissueParameters.gray_matter(3.0)
wm = TissueParameters.white_matter(3.0)
csf = TissueParameters.csf(3.0)

# 7T parameters
gm_7t = TissueParameters.gray_matter(7.0)

# Custom tissue
liver = TissueParameters(
    name="Liver",
    t1=0.812,
    t2=0.042,
    t2_star=0.028,
    density=0.9
)

Desktop app build (PyInstaller)

One build per OS is required (macOS build won’t run on Windows/Linux).

Prereqs

  • macOS: Xcode CLT; brew install libomp.
  • Windows: Python 3.8+ and MSVC Build Tools (for C extension).
  • Linux: gcc/g++; ensure libgomp available.

Quick build (any OS)

python -m pip install -r requirements.txt
python -m pip install pyinstaller
python setup.py build_ext --inplace
PYINSTALLER_CONFIG_DIR=.pyinstaller pyinstaller bloch_gui.spec --noconfirm

Artifact: dist/BlochSimulator (single binary; .exe on Windows).

One-liner helper

./scripts/build_pyinstaller.sh   # creates a venv, installs deps, builds, packages

Run the packaged app

  • macOS/Linux: ./dist/BlochSimulator
  • Windows: dist\\BlochSimulator.exe

Runtime data/exports

  • rfpulses/ is bundled automatically.
  • Exports default to per-user data dirs:
    • macOS: ~/Library/Application Support/BlochSimulator/exports
    • Windows: %APPDATA%\\BlochSimulator\\exports
    • Linux: ~/.local/share/BlochSimulator/exports
  • Override with BLOCH_APP_DIR or BLOCH_EXPORT_DIR if you need a custom location.

Theory

The simulator solves the Bloch equations:

dM/dt = γ(M × B) - [Mx/T2, My/T2, (Mz-M0)/T1]

Using:

  • Rotation matrices for RF and gradient effects
  • Exponential decay for relaxation
  • Cayley-Klein parameters for efficient rotation calculation

Troubleshooting

Build Issues

  1. Missing compiler: Install gcc (Linux), Xcode (macOS), or Visual Studio (Windows)
  2. OpenMP not found: The code will still work but without parallelization
  3. Import error: Ensure the .so/.pyd file is in the same directory

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new features
  4. Submit a pull request

Citation

If you use this simulator in your research, please cite:

@software{bloch_simulator_python,
  title={Python Bloch Equation Simulator GUI and API},
  author={Luca Nagel},
  year={2025},
  url={https://github.com/LucaNagel/bloch_sim_gui}
}

Acknowledgments

This project is based on code originally developed by Brian Hargreaves at Stanford University. Currently (11/2025) it is unfortunately not available. A python adaption of this code can be found here.

  • Original Bloch simulator by Brian Hargreaves, Stanford University
  • NumPy and SciPy communities
  • PyQt/PySide developers
  • OpenMP project
  • Built partially with codex, claude code and gemini cli

Contact

Luca Nagel

Appendix: File Structure

bloch_simulator/
├── bloch_core_modified.c   # C implementation (from original)
├── bloch_core.h            # C header file
├── bloch_wrapper.pyx       # Cython wrapper
├── setup.py                # Build configuration
├── build.py                # Build script
├── bloch_simulator.py      # Python API
├── bloch_gui.py           # GUI application
├── requirements.txt        # Dependencies
└── README.md              # This file

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blochsimulator-1.0.0.tar.gz (353.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

blochsimulator-1.0.0-cp312-cp312-macosx_11_0_arm64.whl (424.0 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file blochsimulator-1.0.0.tar.gz.

File metadata

  • Download URL: blochsimulator-1.0.0.tar.gz
  • Upload date:
  • Size: 353.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for blochsimulator-1.0.0.tar.gz
Algorithm Hash digest
SHA256 9c1aea84bc96cd3a775ef758b88994db22afceda332bd5482f45b1f2160252d3
MD5 c21e6580b98fdc86cb3dbead8682fe05
BLAKE2b-256 00132b6e9cc56abf7994874bd42f6fb896c5728a83579f426e791eae5aadb939

See more details on using hashes here.

File details

Details for the file blochsimulator-1.0.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for blochsimulator-1.0.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3361d8238979def2dedb40eec775ec23c0368f5fea8184045bf9cc7c57751e5f
MD5 8dcd4925c5aa0b265f07eb5ee1a02bf5
BLAKE2b-256 ef946db5c6d711d22523d003831344895d4423b84ace21e61710f5aa90fe2d54

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page