Skip to content

Read the sequence description from ISMRMRD waveforms; description's RF raster by default; 20 mm non-selective rule - #53

Merged
mcencini merged 3 commits into
mainfrom
seqdesc-waveforms
Nov 3, 2026
Merged

mcencini merged 3 commits into
mainfrom
seqdesc-waveforms

Conversation

@mcencini

@mcencini mcencini commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Matteo

What changed

  • Waveform form of the description. read_mrd_description reads the description as ISMRMRD waveforms 1024 (header), 1025 (event list) and 1026 (one per RF definition), the form pulserver sends from Sequence description: one repetition at the k-space centre, as ISMRMRD waveforms pulserver#339. It passes physiological waveforms over. The TEXT message form is no longer read: pulserver no longer sends it, and no stored series holds one. A new description_from_waveforms reads the description off a stored series' waveforms (ismrmrd.Waveform objects or (id, data) pairs).
  • RF raster default. EpgEngine.simulate and simulate_subspace now take rf_raster_time_s from the description by default, instead of 1 µs.
  • 20 mm rule. A pulse whose bandwidth over its slice-select gradient exceeds NONSELECTIVE_THICKNESS_M (20 mm) is tabulated without bandwidth, so a slice profile takes it at its centre rotation: a slab the encoding resolves. A description stating no gradient or no bandwidth keeps the old behaviour.

Why

  • On 7 T data (3D FSE, 3 Nov 2026), the description was not stored with the series, because ISMRMRD HDF5 has no table for TEXT.
  • With the 1 µs default, a description on the scanner's 2 µs raster had every flip halved. Shaped echo trains came out 2–30× low.

Validation

  • pytest tests/sequence: 1006 passed after removing the TEXT path (the full suite passed at 1490 before that). New tests:
    • the physiological waveforms ahead of the description are passed over;
    • a kept series reads its description from its waveforms;
    • a pulse is integrated on the raster its description states;
    • a slab thicker than the threshold is profiled as its centre.
  • ruff check and ruff format --check: clean.
  • End to end on the 7 T series: pulserver's waveforms, decoded here with default arguments, reproduce fse_description for the same train to 0.07 %, with or without exact_slice_profile. The slabs read as 180 and 255 mm.

Documentation impact

The developer guide's MRD stream section now gives the waveform layout. explanations/description.md and explanations/epg.md list the new claims with their tests.

🤖 Generated with Claude Code

…e description's raster; profile only pulses thinner than 20 mm

Pulserver now sends the description as waveforms 1024-1026, which every MRD
writer keeps with the series; read_mrd_description reads them (and still the
TEXT message), and description_from_waveforms reads a stored series'.

EpgEngine.simulate and simulate_subspace integrated pulses on a 1 us raster
unless told otherwise, whatever the description stated; on a scanner's 2 us
raster every flip came out halved. The description's raster is now the default.

A pulse whose bandwidth over its slice-select gradient exceeds
NONSELECTIVE_THICKNESS_M (20 mm) is a slab the encoding resolves: a slice
profile takes it at its centre rotation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pulserver no longer sends the TEXT message, and no series that carries one is
kept.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mcencini
mcencini marked this pull request as ready for review November 3, 2026 23:11
@mcencini
mcencini merged commit c2ce3f3 into main Nov 3, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant