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
- Python 3.7+
- C Compiler:
- Linux:
gcc(usually pre-installed) - macOS: Xcode Command Line Tools (
xcode-select --install) - Windows: Visual Studio Build Tools
- Linux:
- 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
libgompavailable.
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
- macOS:
- Override with
BLOCH_APP_DIRorBLOCH_EXPORT_DIRif 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
- Missing compiler: Install gcc (Linux), Xcode (macOS), or Visual Studio (Windows)
- OpenMP not found: The code will still work but without parallelization
- Import error: Ensure the .so/.pyd file is in the same directory
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c1aea84bc96cd3a775ef758b88994db22afceda332bd5482f45b1f2160252d3
|
|
| MD5 |
c21e6580b98fdc86cb3dbead8682fe05
|
|
| BLAKE2b-256 |
00132b6e9cc56abf7994874bd42f6fb896c5728a83579f426e791eae5aadb939
|
File details
Details for the file blochsimulator-1.0.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: blochsimulator-1.0.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 424.0 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3361d8238979def2dedb40eec775ec23c0368f5fea8184045bf9cc7c57751e5f
|
|
| MD5 |
8dcd4925c5aa0b265f07eb5ee1a02bf5
|
|
| BLAKE2b-256 |
ef946db5c6d711d22523d003831344895d4423b84ace21e61710f5aa90fe2d54
|