Repository navigation
Fit mobafit's water/fat, diffusion and Z-spectrum models with TorchSim - #112
Merged
Merged
Conversation
Each closed-form model the signal tool and mobasig compute is held to single-precision round-off against its TorchSim simulator: Look-Locker in three variants, MOLLI, IR-bSSFP, spin echo with and without inversion, the stimulated-echo train, water and fat in all five multi-echo models and both fat spectra, diffusion, the Lorentzian Z-spectrum and both ASL labellings. The module skips on a TorchSim without them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
…e app -G (WF, WFR2S, R2S, PHASEDIFF), -D and -M with --init are fitted with TorchSim's closed forms; -G -m 2, -P and -M without a start stay on BART. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
…dels-torchsim-87edyf
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Fits from --init for -G -m 0, 1 and 3, and the routes to the command for a start with no fat, -M without a start and -m 5. -m 2's refusal is checked before the model table, which does not carry it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
… runs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
The bisection steps, their scripts and the faulthandler timeout, whose dump went to pytest's capture rather than the log. The hour's limit on a test job stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
On Windows BART's vdprintf opened a stream over the descriptor for every call and never closed it, and a CFL header is a few dozen calls, so a process that had written a few dozen files through BART's commands ran out of the C runtime's streams. The next create_cfl failed inside its OpenMP critical section, BART's error left the section held, and the next command waited on it: the Windows suite hung after test_cli's magnitude mobafit, in the FINUFFT agreement check conftest runs. The fork now formats into memory and writes with _write (pulserver/bart da80f03f). test_cli writes sixty-four files through the command in one process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
BART's error leaves a command by a long jump, and a jump out of an OpenMP critical section skips the call that leaves it. An unknown option or regularization term is raised inside the section BART parses options in, a missing input inside the one every file is loaded in, and the next command to enter either one waited for ever. src/csrc/substitute/critical.c defines the runtime's critical-section entry points, clang's __kmpc_critical family and GCC's GOMP_critical_*, hidden inside the library. Each forwards to the runtime the library is bound to and records per thread the sections held. bartorch_command and guarded leave whatever is still held once the catch returns, and a thread entering a section it already holds leaves the stale one first, which BART's cleanup after a failed command needs. A test in test_core runs each of the three failures and then two good commands in a child process with a timeout; without this change it times out. cli._missing stays, for the app route, which reads its inputs in Python. BART is re-pinned to the merge of pulserver/bart#5 on downstream, the same tree as the commit pinned before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Matteo · project thread
What changed
Before:
bartorch mobafitwent through the app only for-T,-Iand-L. Water/fat (-G), diffusion (-D) and Lorentzian Z-spectra (-M) ran as the BART command.After: those three are also fitted by
apps.mobafit, using TorchSim's closed forms. They come out in BART's coefficient layout and units:-G(models 0, 1, 3 and 4), a complex amplitude with a fat fraction and a fat phase is mapped back to W, F, R2* and fB0.-D, the model is TorchSim's diffusion decay.-M, the model is TorchSim's Lorentzian lines;-Mgoes through the app when--initis given.The following still run as the command:
-G -m 2, whose separate water and fat decays do not converge in the bounded fit.-P.-Mwithout a start.--fB0-init.TorchSim's floor is raised to 0.0.7, the first release with these simulators (FiRMLAB-Pisa/torchsim#20).
A failed BART command no longer hangs the process
Before: on Windows the suite hung partway through. BART's Windows
vdprintfopened a stdio stream per call and never closed it, so after a few dozen CFL filescreate_cflfailed. On every platform, an error raised inside an OpenMP critical section left that section locked, so the next command waited on it forever. This happened after a bad option or-Rterm, or a missing input.After:
downstreammerge of pulserver/bart#5, which writes through_write.src/csrc/substitute/critical.cdefines the runtime's critical-section entry points (__kmpc_criticalfor clang,GOMP_critical_*for GCC) hidden inside the library. Each forwards to the runtime the library is bound to and records per thread which sections are held.bartorch_commandandguardedleave whatever is still held once BART's error catcher returns.tests/test_core.pyruns each of those three failures followed by two good commands in a child process with a timeout. Without the change it times out.Why
Signal simulation belongs to TorchSim rather than to BART.
tests/test_signal_models.pypins every closed-form model BART ships, fromsignalandmobasig, to its TorchSim simulator within single-precision round-off. The models covered are Look-Locker (three variants), MOLLI, IR-bSSFP, spin echo and IR spin echo, the TSE generating function, water/fat, ASL (continuous and pulsed), the five multi-echo models, the Middleton fat spectrum at 1.5 T, diffusion, and Lorentzian Z-spectra.Validation
./scripts/lint.sh: all checks passed, codespell included.libbartorch.so: 2304 passed, 132 skipped, 2 failed.tests/test_openmp.py, which fails locally only because the clang build loads LLVM's libomp next to torch's libgomp. CI builds with GCC 14.mobafitroutes are held against the command intests/test_cli.py, to the tolerance the existing-T/-I/-Lroutes use.Public API and documentation
There are no new public names.
docs/api/cli.mdandAGENTS.mdnow list the new routes and what still goes to BART, anddocs/guides/user/prerequisites.mdnames TorchSim 0.0.7.AGENTS.mdalso describes the critical-section release under Errors.🤖 Generated with Claude Code
https://claude.ai/code/session_01FavM1ptGCKq51oher8tVd9
Generated by Claude Code