Skip to content

Adjust converter to enable dataset processing even if errors occur#69

Merged
yuliadub merged 5 commits into
mainfrom
yuliadub/mrd-converter-changes
Jun 18, 2026
Merged

Adjust converter to enable dataset processing even if errors occur#69
yuliadub merged 5 commits into
mainfrom
yuliadub/mrd-converter-changes

Conversation

@yuliadub

Copy link
Copy Markdown
Collaborator

Tested this on FastMRI knee and brain data, as well as Mosaic (new data source) data. Brain data and mosaic data was not converting correctly, below is the summary of why, both appear as artifacts of how the data we acquired was built.

Slice count (header 32 vs dataset 16, your brain file)
The fastMRI public brain release intentionally ships only a subset of the acquired slices (typically the diagnostically central ones) to control file size. The XML header is preserved verbatim from the original Siemens acquisition, which had the full 32. The fastMRI documentation/papers note this — the slice subsetting is a release-time decision, not a corruption. Trusting the dataset's first axis is the right call.

Axis order swap (Siemens twix file) — non-conforming layout.
The data is internally consistent (640 still matches matrix_size.x. What's broken is the storage convention — whoever repackaged the twix dump into the fastMRI HDF5 layout wrote phase-encode-first instead of readout-first. The samples themselves are intact, just transposed. So reconstruction will be correct as long as transpose happens on read, which is what the swapped branch does. Worth flagging upstream as a metadata/layout bug in the repackager, but the pixel data is fine.

@naegelejd

Copy link
Copy Markdown
Collaborator

Per our discussion, I think we need to clean the MRD header too, so the file produced by the converter is internally consistent 😄

When slice count differs:

  • header.encoding[0].encoding_limits.slice.maximum → set to minimum + num_slices - 1 (don't assume minimum is 0).
  • header.encoding[0].encoding_limits.slice.center → clamp into the new [minimum, maximum] range if it falls outside.

When channel count differs:

  • header.acquisition_system_information.receiver_channelsnum_channels.
  • header.acquisition_system_information.coil_label → truncate to num_channels if longer.

@naegelejd

Copy link
Copy Markdown
Collaborator

Also, the conda build failed because of an upstream issue with the xsd library that ismrmrd uses.

I've already fixed it in #66, and John approved, so I'll merge it now.

@yuliadub yuliadub requested a review from naegelejd June 15, 2026 20:17
Comment thread python/mrd/tools/fastmri_to_mrd.py Outdated
num_channels = dset.shape[1] if dset.ndim == 4 else 1

_reconcile_slice_count(encoding_limits, num_slices, "K-space")
if dset.ndim == 4 and num_channels != header_channels:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the condition if dset.ndim == 4 is incorrect and should just be removed.

If the data has only one channel/coil, then dset.ndim == 3, but we still need to make sure the MRD Header only has one coil label.

And you might as well put this block into a _reconcile_coil_count() helper function too for symmetry 👍

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me know if I got that right :)

@yuliadub yuliadub requested a review from naegelejd June 17, 2026 22:11
@yuliadub yuliadub merged commit 5ca6152 into main Jun 18, 2026
13 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.

2 participants