mne-tools / mne-bids-pipeline

Automatically process entire electrophysiological datasets using MNE-Python.
https://mne.tools/mne-bids-pipeline/
BSD 3-Clause "New" or "Revised" License
137 stars 65 forks source link

ENH: Improve FLASH BEM support #713

Open larsoner opened 1 year ago

larsoner commented 1 year ago

I thought it would be trivial to get MBP to run FLASH for ds000117, but it wasn't. I ended up needing to read some MRI JSON files and write some files:

FLASH synthesis code ``` """Create FLASH BEM surfaces for ds000117. https://openneuro.org/datasets/ds000117/versions/1.0.5 Reconstructed with FreeSurfer:: $ export SUBJECT=sub-09 && export SUBJECTS_DIR=~/mne_data/ds000117-full/derivatives/subjects && mkdir -p ${SUBJECTS_DIR}/${SUBJECT}/mri/orig && mri_convert ~/mne_data/ds000117-full/${SUBJECT}/ses-mri/anat/${SUBJECT}_ses-mri_acq-mprage_T1w.nii.gz ${SUBJECTS_DIR}/${SUBJECT}/mri/orig/001.mgz && recon-all -all -subjid ${SUBJECT} """ import json import pathlib import subprocess import mne data_path = pathlib.Path('~/mne_data/ds000117-full').expanduser().resolve(True) subjects_dir = data_path / 'derivatives' / 'subjects' subjects_dir.mkdir(exist_ok=True) echos = [ json.loads((data_path / f'run-1_echo-{ei}_FLASH.json').read_text()) for ei in range(1, 8) ] for subj_num in range(1, 17): print('*' * 80) subject = f'sub-{subj_num:02d}' print(f'Running subject {subject}') print('*' * 80) in_dir = data_path / subject / 'ses-mri' / 'anat' out_dir = subjects_dir / subject / 'mri' / 'flash' out_dir.mkdir(exist_ok=True) for ei, echo in enumerate(echos, 1): in_flash = in_dir / f'{subject}_ses-mri_run-1_echo-{ei}_FLASH.nii.gz' out_flash = out_dir / f'mef05_{ei:03d}.mgz' if out_flash.is_file(): continue tr = echo['RepetitionTime'] * 1000 te = echo['EchoTime'] * 1000 cmd = [ 'mri_convert', '-tr', f'{tr}', '-te', f'{te}', '-flip_angle', '5', str(in_flash), str(out_flash), ] subprocess.check_call(cmd) pm_fname = out_dir / 'parameter_maps' / 'flash5.mgz' if not pm_fname.is_file(): mne.bem.convert_flash_mris( subject=subject, subjects_dir=subjects_dir, flash5=True, flash30=False) assert pm_fname.is_file() bem_dir = subjects_dir / subject / 'bem' if not (bem_dir / 'inner_skull.surf').is_file(): mne.bem.make_flash_bem( subject=subject, subjects_dir=subjects_dir, overwrite=True, show=True, register=True, verbose=True) ```

I think in principle if the FLASH info exists, we should be able to do the individual-echo writing and synthesis if necessary. Perhaps we are cheating a bit with ds000248 because subjects/sub-01/mri/flash/mef05.mgz already exists.

Or maybe instead we should propose amending ds000117 with the mef05.mgz already present...

agramfort commented 1 year ago

it's very possible we hard coded stuff for ds00248

have you tried the pipeline with ds000117? that can be a good test bed

Message ID: @.***>

larsoner commented 1 year ago

We discussed this in the latest dev meeting -- we could try to add support for this via a get_flash_image callable, but it's tricky for ds000117 because its FreeSurfer derivatives are incomplete (T1.mgz isn't even there) and organized in a non-standard way (nested as derivatives/freesurfer/sub-01/ses-mri/anat/surf etc. rather than derivatives/freesurfer/sub-01/surf).

My suggestion would be to add this if we see that there are others who would benefit from it...