blochtwin 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- blochtwin-0.3.1/.gitignore +34 -0
- blochtwin-0.3.1/CHANGELOG.md +164 -0
- blochtwin-0.3.1/CITATION.cff +44 -0
- blochtwin-0.3.1/LICENSE +24 -0
- blochtwin-0.3.1/NOTICE +11 -0
- blochtwin-0.3.1/PKG-INFO +197 -0
- blochtwin-0.3.1/README.md +123 -0
- blochtwin-0.3.1/blochtwin/__init__.py +100 -0
- blochtwin-0.3.1/blochtwin/_version.py +6 -0
- blochtwin-0.3.1/blochtwin/backend.py +201 -0
- blochtwin-0.3.1/blochtwin/bloch/__init__.py +46 -0
- blochtwin-0.3.1/blochtwin/bloch/engine.py +189 -0
- blochtwin-0.3.1/blochtwin/bloch/isochromat.py +56 -0
- blochtwin-0.3.1/blochtwin/bloch/operators.py +124 -0
- blochtwin-0.3.1/blochtwin/cli.py +281 -0
- blochtwin-0.3.1/blochtwin/io/__init__.py +31 -0
- blochtwin-0.3.1/blochtwin/io/download.py +300 -0
- blochtwin-0.3.1/blochtwin/io/ismrmrd_io.py +120 -0
- blochtwin-0.3.1/blochtwin/kspace/__init__.py +23 -0
- blochtwin-0.3.1/blochtwin/kspace/encoding.py +102 -0
- blochtwin-0.3.1/blochtwin/phantom/__init__.py +21 -0
- blochtwin-0.3.1/blochtwin/phantom/phantom.py +200 -0
- blochtwin-0.3.1/blochtwin/phantom/sources.py +108 -0
- blochtwin-0.3.1/blochtwin/phantom/synthetic.py +231 -0
- blochtwin-0.3.1/blochtwin/physics/__init__.py +33 -0
- blochtwin-0.3.1/blochtwin/physics/tables.py +314 -0
- blochtwin-0.3.1/blochtwin/physics/tissue.py +57 -0
- blochtwin-0.3.1/blochtwin/recon/__init__.py +11 -0
- blochtwin-0.3.1/blochtwin/recon/cartesian.py +19 -0
- blochtwin-0.3.1/blochtwin/sequence/__init__.py +37 -0
- blochtwin-0.3.1/blochtwin/sequence/families.py +364 -0
- blochtwin-0.3.1/blochtwin/sequence/rf.py +76 -0
- blochtwin-0.3.1/blochtwin/sequence/sequence.py +188 -0
- blochtwin-0.3.1/blochtwin/simulator.py +206 -0
- blochtwin-0.3.1/blochtwin/viz/__init__.py +13 -0
- blochtwin-0.3.1/blochtwin/viz/inspect.py +58 -0
- blochtwin-0.3.1/blochtwin/viz/sequence_plot.py +63 -0
- blochtwin-0.3.1/examples/README.md +24 -0
- blochtwin-0.3.1/examples/quickstart.py +98 -0
- blochtwin-0.3.1/examples/simulate_mvp.py +64 -0
- blochtwin-0.3.1/pyproject.toml +100 -0
- blochtwin-0.3.1/tests/test_backend.py +66 -0
- blochtwin-0.3.1/tests/test_bloch.py +151 -0
- blochtwin-0.3.1/tests/test_ismrmrd_io.py +49 -0
- blochtwin-0.3.1/tests/test_package.py +62 -0
- blochtwin-0.3.1/tests/test_phantom.py +108 -0
- blochtwin-0.3.1/tests/test_phantom_sources.py +108 -0
- blochtwin-0.3.1/tests/test_physics_tables.py +119 -0
- blochtwin-0.3.1/tests/test_sequence_families.py +110 -0
- blochtwin-0.3.1/tests/test_sequence_io.py +69 -0
- blochtwin-0.3.1/tests/test_simulate.py +100 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
**/.DS_Store
|
|
3
|
+
|
|
4
|
+
# Python
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*.egg-info/
|
|
8
|
+
.eggs/
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# Test / coverage / cache
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
.coverage
|
|
22
|
+
htmlcov/
|
|
23
|
+
.mypy_cache/
|
|
24
|
+
|
|
25
|
+
# Generated artifacts (phantoms, sequences, raw data) — never commit data
|
|
26
|
+
*.npz
|
|
27
|
+
*.seq
|
|
28
|
+
*.h5
|
|
29
|
+
*.nii
|
|
30
|
+
*.nii.gz
|
|
31
|
+
!references/**
|
|
32
|
+
|
|
33
|
+
# Local datasets (third-party, never commit)
|
|
34
|
+
data/
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
이 프로젝트는 [Semantic Versioning](https://semver.org)을 따릅니다(pre-1.0에서는 minor = 마일스톤).
|
|
4
|
+
릴리스 노트는 "무엇이 새로운가 · 연구자가 할 수 있는 것 · 구현한 물리와 논문" 순서로 씁니다.
|
|
5
|
+
|
|
6
|
+
## [0.3.1] — 2026-10-29 · BlochTwin으로 이름 변경 · PyPI 첫 배포
|
|
7
|
+
|
|
8
|
+
### 이름 변경: PhantomMRI → **BlochTwin** · PyPI 첫 배포
|
|
9
|
+
- 패키지와 import 이름은 `blochtwin`(`pip install blochtwin`, `import blochtwin as bt`), CLI는 `blochtwin`.
|
|
10
|
+
- 이름을 바꾼 이유: MRI에서 "phantom"은 QA용 실물 팬텀을 가리켜 검색 결과와 의미가 겹친다. 새 이름은
|
|
11
|
+
Bloch 방정식으로 스캐너를 재현하는 디지털 트윈이라는 정체성을 드러낸다.
|
|
12
|
+
|
|
13
|
+
### 시퀀스 패밀리 추가: FLAIR / Inversion Recovery
|
|
14
|
+
- **`InversionRecovery`** (180° invert → TI → 90°–180° SE readout) + **`FLAIR`** preset:
|
|
15
|
+
반전회복으로 특정 조직을 null하고 SE로 T2 가중을 얹음. STIR(지방 null)·T1-FLAIR·FLAIR(CSF
|
|
16
|
+
null)가 모두 같은 물리(TI/TE만 다름).
|
|
17
|
+
- **`FLAIR`** 기본값(3T): TI 2500 ms로 **CSF를 null**(T1≈4300ms, TR 9000ms), TE 90 ms T2 가중.
|
|
18
|
+
결과: CSF가 어둡게, 뇌조직은 T2 가중(병변 강조) — 임상 FLAIR 대비와 일치. 검증: CSF 신호
|
|
19
|
+
< WM의 10%, IR-SE 엔진 vs 닫힌 해 0.000%(null 근처 제외).
|
|
20
|
+
- **`null_ti_ms(t1, tr)`** 헬퍼: 임의 조직/필드의 null TI 계산(유한 TR 보정 포함).
|
|
21
|
+
- CLI: `blochtwin simulate --seq flair`(또는 `--seq ir --ti …`).
|
|
22
|
+
|
|
23
|
+
### 팬텀 소스 선택 (실제 사람 머리 해부 경로)
|
|
24
|
+
- **절차적 팬텀에 공기강 추가**(`build_brain_phantom(sinuses=True)` 기본): 비강·상악/전두/
|
|
25
|
+
접형 부비동·이도(ear canal) 공기 주머니를 carve → 공기/조직 경계 생성(M3 susceptibility 대비).
|
|
26
|
+
- **팬텀 소스 registry + 통합 API**(`bt.load_phantom(source=...)`, `bt.list_phantom_sources()`):
|
|
27
|
+
`procedural`(내장) / `brainweb`(실제 뇌) / `nyhead`(실제 머리: scalp/skull/CSF/GM/WM/공기) 중
|
|
28
|
+
선택. 외부 소스는 **번들 금지**·라이선스 게이트.
|
|
29
|
+
- **New York Head 로더**(`load_nyhead`) + 일반 분할 머리 로더(`load_segmented_head`):
|
|
30
|
+
6구획 분할(부비동·콧구멍 공기 포함)을 9조직으로 매핑 — 정확히 "skin+bone+skull(공기강)" 충족.
|
|
31
|
+
실데이터는 사용자가 다운로드(`nyhead_license_notice()`), 로딩/매핑 로직은 합성 fixture로 검증.
|
|
32
|
+
- CLI: `blochtwin phantom --source {procedural,brainweb,nyhead} [--path …] [--list-sources]`.
|
|
33
|
+
- 테스트 89개 통과. ROADMAP M1의 "New York Head 흡수 검토" → 로더 구현 완료.
|
|
34
|
+
|
|
35
|
+
## [0.3.0] — 2026-06-10 · MVP: Bloch 시뮬 + k-space + recon (M2) ⭐
|
|
36
|
+
|
|
37
|
+
**시뮬레이터의 심장 완성.** 파라미터 → **물리적으로 올바른 복소 k-space → 영상**이 한 바퀴
|
|
38
|
+
돕니다. 외부 연구자에게 처음으로 쓸모 있어지는 MVP 라인입니다. 대비(T1/T2/T2* weighting)는
|
|
39
|
+
하드코딩이 아니라 Bloch 물리에서 자연히 나옵니다.
|
|
40
|
+
|
|
41
|
+
### 무엇이 새로운가
|
|
42
|
+
- **Forward 시뮬레이터**(`simulate`): 팬텀 + GRE/SE 시퀀스 → 복소 k-space → iFFT recon 영상,
|
|
43
|
+
결정론적 스캔타임. 코일 1개·full-Cartesian.
|
|
44
|
+
- **operator-splitting Bloch 엔진**(`blochtwin.bloch`): 회전(Rodrigues) ∘ 이완으로 분해,
|
|
45
|
+
PyTorch **미분 가능**. GRE/SE 정상상태 신호의 **해석적 닫힌 해와 기계정밀도로 일치**.
|
|
46
|
+
- **T2\* = 가역 vs 비가역 디페이징**: 비가역 T2 위에 가역 R2'=1/T2*−1/T2를 얹고, 180° 펄스가
|
|
47
|
+
R2'를 refocus. GRE(refocus 없음)는 T2\*, SE는 T2 — **대비가 refocusing 구조에서 emergent**.
|
|
48
|
+
(literal isochromat 앙상블 경로도 `mode="isochromat"`로 제공.)
|
|
49
|
+
- **시퀀스 패밀리 GRE·SE**(`GradientEcho`/`SpinEcho`): Bloch 이벤트 타임라인 + Pulseq `.seq` +
|
|
50
|
+
해석적 닫힌 해 + 스캔타임을 한 파라미터셋에서 모두 도출.
|
|
51
|
+
- **교체 가능 RF shape**(`RFPulse`): apodized sinc + slice-rephasing, TBW 파라미터화.
|
|
52
|
+
- **k-space + recon**: image→k-space FFT + 매트릭스 크롭(유한 해상도·Gibbs 자연 발생),
|
|
53
|
+
Cartesian iFFT recon, 선택적 복소 가우시안 k-space 노이즈(→ Rician).
|
|
54
|
+
- **시퀀스 뷰어 + 결과 표시**(`blochtwin.viz`, lazy matplotlib), CLI `simulate` 명령.
|
|
55
|
+
|
|
56
|
+
### 연구자가 할 수 있는 것
|
|
57
|
+
- TR/TE/flip/FOV/matrix/필드세기를 바꿔 GRE(T2\*/T1 가중)·SE(T2 가중) 영상을 직접 생성.
|
|
58
|
+
- 복소 k-space·영상·조직별 정상상태 신호·정확한 스캔타임을 한 번에 획득(기초 합성 데이터).
|
|
59
|
+
- `blochtwin simulate --seq se --te 90` 한 줄로 T2 가중 영상 + 스캔타임 확인.
|
|
60
|
+
- diff-MRI: 신호가 flip 등에 미분 가능(autograd 그래프 보존).
|
|
61
|
+
|
|
62
|
+
### 구현한 물리·논문
|
|
63
|
+
- **Bloch 방정식** — *Bloch 1946.* **연산자 분리** — *Lauzon 2020 · SIMRI (Benoit-Cattin 2005).*
|
|
64
|
+
- **k-space = gradient 적분, 신호 = Fourier 샘플** — *Twieg 1983 · Ljunggren 1983.*
|
|
65
|
+
- **GRE/SE 정상상태 신호식** — 표준 공학 텍스트(Nishimura; Bernstein-King-Zhou).
|
|
66
|
+
- **영상 노이즈 = k-space 복소 가우시안 → Rician** — *Gudbjartsson-Patz 1995.*
|
|
67
|
+
- 미분 가능 코어 정신 — *MRzero (Loktyushin 2021) · PDG (Endres 2024).*
|
|
68
|
+
|
|
69
|
+
### 검증 결과 (`pytest`, 79 passed)
|
|
70
|
+
- **충실도 게이트 (KomaMRI 수치 대조 완료):** KomaMRI.jl(Castillo-Passi 2023)을 실제로 설치해
|
|
71
|
+
동일 단일-voxel 실험(spin echo=T2, inversion recovery=T1, flip angle=excitation; WM/GM/CSF)을
|
|
72
|
+
대조 → **BlochTwin vs KomaMRI mean-abs-diff = 0.0023% (worst 0.011%), 게이트 <0.1% 통과.**
|
|
73
|
+
BlochTwin은 해석적 Bloch 식과 기계정밀도(0.000%)로 일치. 재현: `benchmarks/compare.py`.
|
|
74
|
+
(정상상태 spoiled GRE는 spoiling 모델 차이 — 우리는 ideal spoiling=Ernst 정확, Koma는 유한
|
|
75
|
+
isochromat gradient spoiling이라 잔류 coherence 수% — 물리 불일치 아님. T2\*는 양쪽 모두
|
|
76
|
+
isochromat 필요. `benchmarks/README.md` 참조.) isochromat 모드는 T2\* 닫힌 해에 <1% 수렴.
|
|
77
|
+
- **대비가 emergent:** SE T2 가중에서 CSF가 가장 밝고, 단TR GRE에서 WM>CSF로 **순서가 시퀀스에
|
|
78
|
+
따라 뒤집힘**(하드코딩 아님). 필드세기 토글이 WM 신호를 바꿈.
|
|
79
|
+
- **수치:** encode/recon round-trip 기계정밀도, 스캔타임 = TR×N_PE×N_avg 단위테스트, 노이즈
|
|
80
|
+
재현성(seed), `.seq` timing 유효, 미분 가능성(∂|Mxy|/∂flip = cos α).
|
|
81
|
+
|
|
82
|
+
### 알려진 한계 / 근사
|
|
83
|
+
- 단일 코일·full-Cartesian·2D 단일 슬라이스. 멀티코일/병렬영상은 M4(v0.5.0).
|
|
84
|
+
- 음향 노이즈·모션/Gibbs/chemical-shift/susceptibility 아티팩트는 M3(v0.4.0).
|
|
85
|
+
- in-plane FOV는 팬텀 슬라이스를 따르고 매트릭스가 해상도를 정함(FOV zoom은 후속).
|
|
86
|
+
- T2\* 기본 경로는 가역/비가역 분리 해석 모델(정확). isochromat 경로는 이산화 오차(개수 의존).
|
|
87
|
+
- KomaMRI **수치** 대조 완료(0.0023%, `benchmarks/`). JEMRIS 대조는 후속.
|
|
88
|
+
|
|
89
|
+
### 설치·예제
|
|
90
|
+
```bash
|
|
91
|
+
pip install blochtwin
|
|
92
|
+
python examples/simulate_mvp.py # 파라미터→k-space→영상, 대비 demo
|
|
93
|
+
blochtwin simulate --seq se --te 90 # CLI 한 줄
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 인용
|
|
97
|
+
[CITATION.cff](CITATION.cff) (v0.3.0). Zenodo version DOI와 arXiv preprint는 이 릴리스 라인에 맞춰
|
|
98
|
+
발행할 예정입니다.
|
|
99
|
+
|
|
100
|
+
## [0.2.0] — 2026-06-10 · 기반 + 팬텀 (M0 + M1) · 조용한 공개
|
|
101
|
+
|
|
102
|
+
**코드 첫 버전.** 외부 표준과 배포
|
|
103
|
+
구조를 못 박고, 시뮬레이터가 먹을 "디지털 객체"인 3D fuzzy 뇌 팬텀을 만들었습니다.
|
|
104
|
+
**아직 신호(Bloch) 시뮬레이션은 없습니다** — 그건 v0.3.0 MVP입니다.
|
|
105
|
+
|
|
106
|
+
### 무엇이 새로운가
|
|
107
|
+
- `blochtwin` headless 수치 코어 패키지(라이브러리 + `blochtwin` CLI). 코어는 **GUI를
|
|
108
|
+
import하지 않습니다**(클러스터 headless 실행 보장, 테스트로 강제).
|
|
109
|
+
- **PyTorch 백엔드 추상화**(`get_backend`): CPU/CUDA/MPS 디바이스 + dtype 해석. 데이터 생성
|
|
110
|
+
기본값은 **CPU/CUDA float64**, MPS는 교육용 float32 경로로만 — 정밀도 정책을 코드로 강제
|
|
111
|
+
(MPS+float64 / MPS+데이터 생성은 에러).
|
|
112
|
+
- **3D fuzzy 뇌 팬텀**(`build_brain_phantom`): ICBM152-유사 격자 위 9개 조직 클래스
|
|
113
|
+
(WM/GM/CSF/skull/skin/fat/glial/connective/background)의 분율 맵. 절차적·결정론적 생성이라
|
|
114
|
+
외부 데이터 없이 바로 돌아갑니다. 부드러운 경계 = partial-volume(경계 voxel이 혼합값).
|
|
115
|
+
- **필드세기별 조직 파라미터 테이블**(`tissue_parameters`, `tissue_table`): 1.5/3/7T의
|
|
116
|
+
T1/T2/T2*/PD/χ를 **출처 태깅과 함께** 제공. Rooney power-law T1(B0), Peters T2*, 화학적
|
|
117
|
+
이동(`chemical_shift_hz`). 7T·glial/connective/skin 값은 정직하게 플래그.
|
|
118
|
+
- **Pulseq `.seq` I/O**(`read_seq`/`write_seq`): PyPulseq 1.5 재사용(직접 재발명 안 함).
|
|
119
|
+
데모 GRE 빌더 포함(round-trip·뷰어용).
|
|
120
|
+
- **ISMRMRD 출력 스텁**(`write_ismrmrd_skeleton`): 유효한 XML 헤더 + HDF5, 표준 리더로 다시
|
|
121
|
+
열림.
|
|
122
|
+
- **BrainWeb/ICBM 다운로더·로더**(`blochtwin.io.download`): 외부 팬텀은 **번들하지 않고**
|
|
123
|
+
사용자가 라이선스 동의 후 받아 같은 `Phantom`으로 적재.
|
|
124
|
+
- **napari 3D 인스펙터**(선택, `blochtwin[viz]`, lazy import).
|
|
125
|
+
- pip extras 골격(`[cuda]/[viz]/[ml]/[app]/[dev]`) + 재현용 Docker 스텁.
|
|
126
|
+
|
|
127
|
+
### 연구자가 할 수 있는 것
|
|
128
|
+
- `pip install blochtwin` 후 fuzzy 조직 분율 팬텀을 만들고 검사(napari).
|
|
129
|
+
- 1.5/3/7T 조직 파라미터 테이블을 인용 출처와 함께 조회(`blochtwin tables --field 7.0`).
|
|
130
|
+
- Pulseq `.seq`를 읽고/쓰고 round-trip 검증, 빈 ISMRMRD 파일을 표준 리더로 열기.
|
|
131
|
+
|
|
132
|
+
### 구현한 물리·논문
|
|
133
|
+
- **부분 체적(partial volume):** voxel 신호 = 조직별 분율 가중합, Σ f_k = 1 —
|
|
134
|
+
*BrainWeb (Collins 1998; Kwan 1999; Aubert-Broche 2006).*
|
|
135
|
+
- **필드 의존 T1 power-law:** WM ≈ 0.583·B0^0.382 s, GM ≈ 0.857·B0^0.376 s, CSF ≈ 4.3 s
|
|
136
|
+
(≈ B0-무관) — *Rooney 2007.*
|
|
137
|
+
- **멀티필드 T2\*** — *Peters 2007.* 3T 이완 앵커 — *Stanisz 2005, Wansapura 1999.*
|
|
138
|
+
자화율 χ — *Schenck 1996.* 화학적 이동 Δf = ppm·γ̄·B0.
|
|
139
|
+
|
|
140
|
+
### 검증 결과 (`pytest`, 48 passed)
|
|
141
|
+
- 팬텀: 분율 합이 voxel당 1에서 최대 ~1e-16 이내, 분율 ∈ [0,1], WM/GM 경계 혼합 voxel 존재.
|
|
142
|
+
- 물리 테이블: 3T WM T1 ≈ 832 ms, GM ≈ 1331 ms, CSF ≈ 4300 ms(인용 범위 내), T1은 필드와
|
|
143
|
+
함께 증가·T2\*는 감소, 모든 값이 출처를 가짐.
|
|
144
|
+
- Pulseq round-trip: 써놓은 `.seq`를 다시 읽어 쓰면 body·서명·duration·k-space 샘플 수 일치.
|
|
145
|
+
- ISMRMRD: 스켈레톤이 표준 `ismrmrd` 리더로 다시 열림, ¹H 공명주파수가 필드에 비례.
|
|
146
|
+
- 표준 호환·재현성: 코어 import가 GUI를 끌어오지 않음(headless), 동일 입력 → 동일 출력.
|
|
147
|
+
|
|
148
|
+
### 알려진 한계 / 근사
|
|
149
|
+
- **신호 시뮬레이션 없음.** 팬텀은 기하·파라미터까지만. parameter→영상은 v0.3.0(Bloch 엔진).
|
|
150
|
+
- **절차적 팬텀은 근사 해부.** 실제 BrainWeb 해부가 필요하면 다운로더로 받아 적재(번들 금지).
|
|
151
|
+
ICBM152 affine은 중심 정렬 근사이며 실제 템플릿에 등록(registration)되지 않음.
|
|
152
|
+
- **7T 조직값은 less-standardized**로 플래그(Rooney 외삽 + Peters). glial/connective/skin은
|
|
153
|
+
표준 brain-MR relaxometry가 없어 인접 조직값을 차용(`approximate` 플래그).
|
|
154
|
+
- 음향 노이즈·아티팩트·멀티코일·CS는 이후 마일스톤(M3~M5).
|
|
155
|
+
|
|
156
|
+
### 설치·예제
|
|
157
|
+
```bash
|
|
158
|
+
pip install blochtwin
|
|
159
|
+
python examples/quickstart.py # 전체 파이프라인 데모
|
|
160
|
+
blochtwin info # 버전·디바이스·상태
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 인용
|
|
164
|
+
[CITATION.cff](CITATION.cff) 참조. v0.2.0 첫 태그에서 Zenodo DOI 자동 발행 예정.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it using the metadata below."
|
|
3
|
+
title: "BlochTwin: a physics-faithful open MRI scanner simulator for synthetic data and teaching"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: "Lee"
|
|
7
|
+
given-names: "Hoonjae"
|
|
8
|
+
alias: "이훈재"
|
|
9
|
+
affiliation: "newmean.ai (Newmean AI)"
|
|
10
|
+
email: "dev@newmean.ai"
|
|
11
|
+
# orcid: "https://orcid.org/0000-0000-0000-0000" # ORCID 발급 후 채울 것
|
|
12
|
+
repository-code: "https://github.com/newmean-ai/blochtwin"
|
|
13
|
+
url: "https://github.com/newmean-ai/blochtwin"
|
|
14
|
+
abstract: >-
|
|
15
|
+
An open, GPU-accelerated, physics-faithful MRI scanner simulator (digital twin)
|
|
16
|
+
for generating realistic synthetic MRI training data and for teaching scanner
|
|
17
|
+
operation (parameter to image and scan-time intuition). Models a high-resolution
|
|
18
|
+
3D brain phantom with partial-volume effects, 1.5T/3T/7T field strengths,
|
|
19
|
+
viewable RF pulse sequences, gradient-coil acoustic noise tied to gradient
|
|
20
|
+
switching, k-space acquisition and reconstruction (with SENSE/GRAPPA/CS on the
|
|
21
|
+
roadmap).
|
|
22
|
+
keywords:
|
|
23
|
+
- MRI
|
|
24
|
+
- simulation
|
|
25
|
+
- digital twin
|
|
26
|
+
- synthetic data
|
|
27
|
+
- Bloch equations
|
|
28
|
+
- k-space
|
|
29
|
+
- deep learning
|
|
30
|
+
- medical imaging
|
|
31
|
+
- acoustic noise
|
|
32
|
+
license: "Apache-2.0"
|
|
33
|
+
version: "0.3.1"
|
|
34
|
+
date-released: "2026-06-10"
|
|
35
|
+
# 동반 논문(MRM 또는 ISMRM abstract) 출간 후 preferred-citation 블록 추가:
|
|
36
|
+
# preferred-citation:
|
|
37
|
+
# type: article
|
|
38
|
+
# title: "..."
|
|
39
|
+
# authors:
|
|
40
|
+
# - family-names: "Lee"
|
|
41
|
+
# given-names: "Hoonjae"
|
|
42
|
+
# journal: "Magnetic Resonance in Medicine"
|
|
43
|
+
# year: 2026
|
|
44
|
+
# doi: "10.1002/mrm.XXXXX"
|
blochtwin-0.3.1/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 Hoonjae Lee (이훈재), newmean.ai
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
18
|
+
|
|
19
|
+
SPDX-License-Identifier: Apache-2.0
|
|
20
|
+
|
|
21
|
+
NOTE: Before the first public release, replace this file with the FULL verbatim
|
|
22
|
+
text of the Apache License 2.0 (the ~11KB canonical text from the URL above).
|
|
23
|
+
Trademark note: see the NOTICE file. "BlochTwin" is a trademark of newmean.ai
|
|
24
|
+
and is not licensed under Apache-2.0.
|
blochtwin-0.3.1/NOTICE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
BlochTwin
|
|
2
|
+
Copyright 2026 Hoonjae Lee (이훈재), newmean.ai
|
|
3
|
+
|
|
4
|
+
This product includes software developed by Hoonjae Lee / newmean.ai.
|
|
5
|
+
|
|
6
|
+
"BlochTwin" and the project name and logo are trademarks of newmean.ai.
|
|
7
|
+
Use of the source code is governed by the Apache License 2.0 (see LICENSE).
|
|
8
|
+
The Apache-2.0 license does NOT grant trademark rights: forks and derivatives
|
|
9
|
+
may not use the "BlochTwin" name, logo, or "BlochTwin-validated" mark without
|
|
10
|
+
permission. Commercial offerings (hosted generation, validated presets,
|
|
11
|
+
validation reports, enterprise support): dev@newmean.ai
|
blochtwin-0.3.1/PKG-INFO
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: blochtwin
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Physics-faithful, GPU-accelerated open-source MRI scanner simulator (digital twin) for synthetic ML training data and scanner-operation teaching.
|
|
5
|
+
Project-URL: Homepage, https://github.com/newmean-ai/blochtwin
|
|
6
|
+
Project-URL: Repository, https://github.com/newmean-ai/blochtwin
|
|
7
|
+
Project-URL: Issues, https://github.com/newmean-ai/blochtwin/issues
|
|
8
|
+
Author-email: Hoonjae Lee <dev@newmean.ai>
|
|
9
|
+
License: Apache License
|
|
10
|
+
Version 2.0, January 2004
|
|
11
|
+
http://www.apache.org/licenses/
|
|
12
|
+
|
|
13
|
+
Copyright 2026 Hoonjae Lee (이훈재), newmean.ai
|
|
14
|
+
|
|
15
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
16
|
+
you may not use this file except in compliance with the License.
|
|
17
|
+
You may obtain a copy of the License at
|
|
18
|
+
|
|
19
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
+
|
|
21
|
+
Unless required by applicable law or agreed to in writing, software
|
|
22
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
23
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
24
|
+
See the License for the specific language governing permissions and
|
|
25
|
+
limitations under the License.
|
|
26
|
+
|
|
27
|
+
SPDX-License-Identifier: Apache-2.0
|
|
28
|
+
|
|
29
|
+
NOTE: Before the first public release, replace this file with the FULL verbatim
|
|
30
|
+
text of the Apache License 2.0 (the ~11KB canonical text from the URL above).
|
|
31
|
+
Trademark note: see the NOTICE file. "BlochTwin" is a trademark of newmean.ai
|
|
32
|
+
and is not licensed under Apache-2.0.
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
License-File: NOTICE
|
|
35
|
+
Keywords: Bloch,ISMRMRD,MRI,Pulseq,digital-twin,k-space,medical-imaging,phantom,simulation,synthetic-data
|
|
36
|
+
Classifier: Development Status :: 3 - Alpha
|
|
37
|
+
Classifier: Intended Audience :: Science/Research
|
|
38
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
44
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
45
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
46
|
+
Requires-Python: <3.14,>=3.10
|
|
47
|
+
Requires-Dist: h5py>=3.8
|
|
48
|
+
Requires-Dist: ismrmrd>=1.14
|
|
49
|
+
Requires-Dist: nibabel>=5.0
|
|
50
|
+
Requires-Dist: numpy>=1.24
|
|
51
|
+
Requires-Dist: pypulseq>=1.5
|
|
52
|
+
Requires-Dist: scipy>=1.10
|
|
53
|
+
Requires-Dist: torch>=2.2
|
|
54
|
+
Provides-Extra: all
|
|
55
|
+
Requires-Dist: monai>=1.3; extra == 'all'
|
|
56
|
+
Requires-Dist: napari>=0.4.18; extra == 'all'
|
|
57
|
+
Requires-Dist: pytest-cov>=4.1; extra == 'all'
|
|
58
|
+
Requires-Dist: pytest>=7.4; extra == 'all'
|
|
59
|
+
Requires-Dist: ruff>=0.4; extra == 'all'
|
|
60
|
+
Requires-Dist: streamlit>=1.30; extra == 'all'
|
|
61
|
+
Provides-Extra: app
|
|
62
|
+
Requires-Dist: streamlit>=1.30; extra == 'app'
|
|
63
|
+
Provides-Extra: cuda
|
|
64
|
+
Requires-Dist: cupy-cuda12x>=12.0; extra == 'cuda'
|
|
65
|
+
Provides-Extra: dev
|
|
66
|
+
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
|
|
67
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
68
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
69
|
+
Provides-Extra: ml
|
|
70
|
+
Requires-Dist: monai>=1.3; extra == 'ml'
|
|
71
|
+
Provides-Extra: viz
|
|
72
|
+
Requires-Dist: napari>=0.4.18; extra == 'viz'
|
|
73
|
+
Description-Content-Type: text/markdown
|
|
74
|
+
|
|
75
|
+
# BlochTwin
|
|
76
|
+
|
|
77
|
+
**A physics-faithful, open-source MRI scanner simulator (digital twin)** for generating
|
|
78
|
+
synthetic MRI training data with perfect ground truth and for learning how scan parameters
|
|
79
|
+
shape the image, the scan time and the artifacts.
|
|
80
|
+
|
|
81
|
+
[](https://pypi.org/project/blochtwin/)
|
|
82
|
+
[](LICENSE)
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
> **Status: alpha (v0.3).** The core loop works end to end: tissue phantom → Bloch
|
|
86
|
+
> simulation → complex k-space → reconstructed image. Multi-coil acquisition, artifacts and
|
|
87
|
+
> gradient acoustic noise are on the roadmap below.
|
|
88
|
+
|
|
89
|
+
## Why
|
|
90
|
+
|
|
91
|
+
MRI deep-learning work needs paired data that real scanners cannot provide. That means
|
|
92
|
+
fully sampled complex k-space, noise-free references, voxel-wise tissue maps and exact
|
|
93
|
+
sequence parameters. Physics simulators (JEMRIS, MRiLab, KomaMRI) produce faithful signals,
|
|
94
|
+
but they are not built as ML data pipelines. ML toolkits (TorchIO, MONAI) are easy to use,
|
|
95
|
+
but they fake k-space as the FFT of a magnitude image. BlochTwin aims at the gap between
|
|
96
|
+
them: real acquisition physics, packaged as a headless Python/PyTorch library.
|
|
97
|
+
|
|
98
|
+
- **Contrast comes from physics, not lookup tables.** Each tissue's signal is computed by an
|
|
99
|
+
operator-splitting Bloch engine. T1, T2 and T2\* weighting follow from TR/TE/TI/flip and
|
|
100
|
+
from the refocusing structure of the sequence.
|
|
101
|
+
- **Every tissue parameter is cited.** Tables for T1, T2, T2\*, PD and χ at 1.5, 3 and 7 T
|
|
102
|
+
carry their literature sources (`blochtwin references`). Less-standardized values, such as
|
|
103
|
+
7 T extrapolations, are flagged.
|
|
104
|
+
- **Differentiable.** The engine is written in PyTorch, so signals keep their autograd graph
|
|
105
|
+
for diff-MRI experiments.
|
|
106
|
+
- **Headless by design.** The core never imports a GUI, so it runs on clusters. Viewers are
|
|
107
|
+
optional.
|
|
108
|
+
|
|
109
|
+
## Install
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install blochtwin # Python 3.10–3.13, CPU/CUDA, Apple MPS for convenience
|
|
113
|
+
pip install 'blochtwin[viz]' # optional napari 3D inspector (add a Qt backend)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Quick start
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import blochtwin as bt
|
|
120
|
+
|
|
121
|
+
phantom = bt.build_brain_phantom(voxel_mm=2.0) # built-in procedural head (incl. air sinuses)
|
|
122
|
+
|
|
123
|
+
# T2-weighted spin echo: CSF bright
|
|
124
|
+
se = bt.simulate(phantom, bt.SpinEcho(matrix=(128, 128), tr_ms=3000, te_ms=100), field_t=3.0)
|
|
125
|
+
print(se.magnitude.shape, se.scan_time_s) # (128, 128) 384.0
|
|
126
|
+
|
|
127
|
+
# T1-weighted spoiled gradient echo: same phantom, different physics, WM bright
|
|
128
|
+
gre = bt.simulate(phantom, bt.GradientEcho(tr_ms=15, te_ms=4, flip_deg=25), field_t=3.0)
|
|
129
|
+
|
|
130
|
+
# FLAIR: inversion recovery that nulls CSF (TI chosen from CSF T1 at 3 T)
|
|
131
|
+
flair = bt.simulate(phantom, bt.FLAIR(), field_t=3.0)
|
|
132
|
+
|
|
133
|
+
kspace, image = gre.kspace, gre.image # complex k-space + reconstruction
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The same from the command line:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
blochtwin simulate --seq se --te 90 # image + k-space + scan time
|
|
140
|
+
blochtwin simulate --seq flair
|
|
141
|
+
blochtwin tables --field 7.0 # cited tissue parameters at 7 T
|
|
142
|
+
blochtwin info
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Real anatomy can be loaded from sources you download yourself. Their data is never bundled
|
|
146
|
+
because it is under third-party licenses:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
bt.list_phantom_sources() # sources + licenses
|
|
150
|
+
bt.load_phantom("brainweb", directory="brainweb/") # BrainWeb fuzzy tissue maps
|
|
151
|
+
bt.load_phantom("nyhead", path="nyhead_seg.nii") # New York Head (scalp/skull/air)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## What works today (v0.3)
|
|
155
|
+
|
|
156
|
+
| Area | Status |
|
|
157
|
+
|---|---|
|
|
158
|
+
| Bloch engine | Operator splitting (rotation ∘ relaxation), differentiable; T2\* via reversible/irreversible split (analytic) or an explicit isochromat ensemble |
|
|
159
|
+
| Sequences | Spin echo, spoiled gradient echo, inversion recovery, FLAIR; apodized-sinc RF with slice rephasing; Pulseq `.seq` export |
|
|
160
|
+
| Phantoms | Fuzzy tissue-fraction model (partial volume built in); procedural head; BrainWeb and New York Head loaders |
|
|
161
|
+
| Physics tables | 1.5 / 3 / 7 T, field-dependent T1 (Rooney power law), cited sources |
|
|
162
|
+
| k-space & recon | Cartesian encoding with matrix crop (Gibbs and resolution emerge naturally), complex Gaussian noise (→ Rician), iFFT recon, deterministic scan time |
|
|
163
|
+
| I/O | Pulseq read/write, ISMRMRD header/skeleton output (full raw export comes with the dataset generator), NIfTI |
|
|
164
|
+
|
|
165
|
+
### Validation
|
|
166
|
+
|
|
167
|
+
- Steady-state GRE and SE signals match closed-form solutions to machine precision. IR
|
|
168
|
+
matches too, except right at the null point.
|
|
169
|
+
- Single-voxel cross-check against **KomaMRI.jl 0.10.4** (SE, IR, flip sweeps over WM, GM and
|
|
170
|
+
CSF): **0.0023 % mean absolute difference** (worst 0.011 %). Reproduce with
|
|
171
|
+
`benchmarks/compare.py`.
|
|
172
|
+
|
|
173
|
+
## Roadmap
|
|
174
|
+
|
|
175
|
+
1. **Artifacts, field strength and acoustics.** Sampling patterns, motion, chemical shift,
|
|
176
|
+
susceptibility, EPI ghosts, and **gradient acoustic noise**, which no open simulator
|
|
177
|
+
models today.
|
|
178
|
+
2. **Multi-coil.** Coil sensitivities, SENSE and GRAPPA.
|
|
179
|
+
3. **Compressed sensing.**
|
|
180
|
+
4. **Dataset generator.** Paired, fastMRI-compatible tuples with domain randomization, plus
|
|
181
|
+
an interactive teaching UI.
|
|
182
|
+
5. **v1.0.** Validation against real data (fastMRI) and a companion paper.
|
|
183
|
+
|
|
184
|
+
## How to cite
|
|
185
|
+
|
|
186
|
+
If you use BlochTwin in academic work, please cite it (see [CITATION.cff](CITATION.cff); a
|
|
187
|
+
Zenodo DOI will be added with the first tagged release). Citation is a community norm we ask
|
|
188
|
+
you to honor, not a license restriction.
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
Apache License 2.0. You are free to use, modify and distribute BlochTwin, including
|
|
193
|
+
commercially. "BlochTwin" and its logo are trademarks of newmean.ai. Forks may use the code
|
|
194
|
+
but not the name or logo (see [NOTICE](NOTICE)).
|
|
195
|
+
|
|
196
|
+
Questions and physics-fidelity reports are welcome on
|
|
197
|
+
[GitHub Issues](https://github.com/newmean-ai/blochtwin/issues) or at dev@newmean.ai.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# BlochTwin
|
|
2
|
+
|
|
3
|
+
**A physics-faithful, open-source MRI scanner simulator (digital twin)** for generating
|
|
4
|
+
synthetic MRI training data with perfect ground truth and for learning how scan parameters
|
|
5
|
+
shape the image, the scan time and the artifacts.
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/blochtwin/)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
> **Status: alpha (v0.3).** The core loop works end to end: tissue phantom → Bloch
|
|
12
|
+
> simulation → complex k-space → reconstructed image. Multi-coil acquisition, artifacts and
|
|
13
|
+
> gradient acoustic noise are on the roadmap below.
|
|
14
|
+
|
|
15
|
+
## Why
|
|
16
|
+
|
|
17
|
+
MRI deep-learning work needs paired data that real scanners cannot provide. That means
|
|
18
|
+
fully sampled complex k-space, noise-free references, voxel-wise tissue maps and exact
|
|
19
|
+
sequence parameters. Physics simulators (JEMRIS, MRiLab, KomaMRI) produce faithful signals,
|
|
20
|
+
but they are not built as ML data pipelines. ML toolkits (TorchIO, MONAI) are easy to use,
|
|
21
|
+
but they fake k-space as the FFT of a magnitude image. BlochTwin aims at the gap between
|
|
22
|
+
them: real acquisition physics, packaged as a headless Python/PyTorch library.
|
|
23
|
+
|
|
24
|
+
- **Contrast comes from physics, not lookup tables.** Each tissue's signal is computed by an
|
|
25
|
+
operator-splitting Bloch engine. T1, T2 and T2\* weighting follow from TR/TE/TI/flip and
|
|
26
|
+
from the refocusing structure of the sequence.
|
|
27
|
+
- **Every tissue parameter is cited.** Tables for T1, T2, T2\*, PD and χ at 1.5, 3 and 7 T
|
|
28
|
+
carry their literature sources (`blochtwin references`). Less-standardized values, such as
|
|
29
|
+
7 T extrapolations, are flagged.
|
|
30
|
+
- **Differentiable.** The engine is written in PyTorch, so signals keep their autograd graph
|
|
31
|
+
for diff-MRI experiments.
|
|
32
|
+
- **Headless by design.** The core never imports a GUI, so it runs on clusters. Viewers are
|
|
33
|
+
optional.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install blochtwin # Python 3.10–3.13, CPU/CUDA, Apple MPS for convenience
|
|
39
|
+
pip install 'blochtwin[viz]' # optional napari 3D inspector (add a Qt backend)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import blochtwin as bt
|
|
46
|
+
|
|
47
|
+
phantom = bt.build_brain_phantom(voxel_mm=2.0) # built-in procedural head (incl. air sinuses)
|
|
48
|
+
|
|
49
|
+
# T2-weighted spin echo: CSF bright
|
|
50
|
+
se = bt.simulate(phantom, bt.SpinEcho(matrix=(128, 128), tr_ms=3000, te_ms=100), field_t=3.0)
|
|
51
|
+
print(se.magnitude.shape, se.scan_time_s) # (128, 128) 384.0
|
|
52
|
+
|
|
53
|
+
# T1-weighted spoiled gradient echo: same phantom, different physics, WM bright
|
|
54
|
+
gre = bt.simulate(phantom, bt.GradientEcho(tr_ms=15, te_ms=4, flip_deg=25), field_t=3.0)
|
|
55
|
+
|
|
56
|
+
# FLAIR: inversion recovery that nulls CSF (TI chosen from CSF T1 at 3 T)
|
|
57
|
+
flair = bt.simulate(phantom, bt.FLAIR(), field_t=3.0)
|
|
58
|
+
|
|
59
|
+
kspace, image = gre.kspace, gre.image # complex k-space + reconstruction
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The same from the command line:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
blochtwin simulate --seq se --te 90 # image + k-space + scan time
|
|
66
|
+
blochtwin simulate --seq flair
|
|
67
|
+
blochtwin tables --field 7.0 # cited tissue parameters at 7 T
|
|
68
|
+
blochtwin info
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Real anatomy can be loaded from sources you download yourself. Their data is never bundled
|
|
72
|
+
because it is under third-party licenses:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
bt.list_phantom_sources() # sources + licenses
|
|
76
|
+
bt.load_phantom("brainweb", directory="brainweb/") # BrainWeb fuzzy tissue maps
|
|
77
|
+
bt.load_phantom("nyhead", path="nyhead_seg.nii") # New York Head (scalp/skull/air)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## What works today (v0.3)
|
|
81
|
+
|
|
82
|
+
| Area | Status |
|
|
83
|
+
|---|---|
|
|
84
|
+
| Bloch engine | Operator splitting (rotation ∘ relaxation), differentiable; T2\* via reversible/irreversible split (analytic) or an explicit isochromat ensemble |
|
|
85
|
+
| Sequences | Spin echo, spoiled gradient echo, inversion recovery, FLAIR; apodized-sinc RF with slice rephasing; Pulseq `.seq` export |
|
|
86
|
+
| Phantoms | Fuzzy tissue-fraction model (partial volume built in); procedural head; BrainWeb and New York Head loaders |
|
|
87
|
+
| Physics tables | 1.5 / 3 / 7 T, field-dependent T1 (Rooney power law), cited sources |
|
|
88
|
+
| k-space & recon | Cartesian encoding with matrix crop (Gibbs and resolution emerge naturally), complex Gaussian noise (→ Rician), iFFT recon, deterministic scan time |
|
|
89
|
+
| I/O | Pulseq read/write, ISMRMRD header/skeleton output (full raw export comes with the dataset generator), NIfTI |
|
|
90
|
+
|
|
91
|
+
### Validation
|
|
92
|
+
|
|
93
|
+
- Steady-state GRE and SE signals match closed-form solutions to machine precision. IR
|
|
94
|
+
matches too, except right at the null point.
|
|
95
|
+
- Single-voxel cross-check against **KomaMRI.jl 0.10.4** (SE, IR, flip sweeps over WM, GM and
|
|
96
|
+
CSF): **0.0023 % mean absolute difference** (worst 0.011 %). Reproduce with
|
|
97
|
+
`benchmarks/compare.py`.
|
|
98
|
+
|
|
99
|
+
## Roadmap
|
|
100
|
+
|
|
101
|
+
1. **Artifacts, field strength and acoustics.** Sampling patterns, motion, chemical shift,
|
|
102
|
+
susceptibility, EPI ghosts, and **gradient acoustic noise**, which no open simulator
|
|
103
|
+
models today.
|
|
104
|
+
2. **Multi-coil.** Coil sensitivities, SENSE and GRAPPA.
|
|
105
|
+
3. **Compressed sensing.**
|
|
106
|
+
4. **Dataset generator.** Paired, fastMRI-compatible tuples with domain randomization, plus
|
|
107
|
+
an interactive teaching UI.
|
|
108
|
+
5. **v1.0.** Validation against real data (fastMRI) and a companion paper.
|
|
109
|
+
|
|
110
|
+
## How to cite
|
|
111
|
+
|
|
112
|
+
If you use BlochTwin in academic work, please cite it (see [CITATION.cff](CITATION.cff); a
|
|
113
|
+
Zenodo DOI will be added with the first tagged release). Citation is a community norm we ask
|
|
114
|
+
you to honor, not a license restriction.
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
Apache License 2.0. You are free to use, modify and distribute BlochTwin, including
|
|
119
|
+
commercially. "BlochTwin" and its logo are trademarks of newmean.ai. Forks may use the code
|
|
120
|
+
but not the name or logo (see [NOTICE](NOTICE)).
|
|
121
|
+
|
|
122
|
+
Questions and physics-fidelity reports are welcome on
|
|
123
|
+
[GitHub Issues](https://github.com/newmean-ai/blochtwin/issues) or at dev@newmean.ai.
|