Coder Social home page Coder Social logo

nipreps / sdcflows Goto Github PK

View Code? Open in Web Editor NEW
30.0 13.0 24.0 57.62 MB

Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes

Home Page: https://www.nipreps.org/sdcflows

License: Apache License 2.0

Python 98.10% Dockerfile 1.81% Makefile 0.09%
magnetic-resonance-imaging echo-planar-imaging nonlinear-distortions image-artifacts

sdcflows's Introduction

SDCFlows

Latest Version https://codecov.io/gh/nipreps/sdcflows/branch/master/graph/badge.svg?token=V2CS5adHYk https://circleci.com/gh/nipreps/sdcflows.svg?style=svg

SDCFlows (Susceptibility Distortion Correction workFlows) is a Python library of NiPype-based workflows to preprocess B0 mapping data, estimate the corresponding fieldmap and finally correct for susceptibility distortions. Susceptibility-derived distortions are typically displayed by images acquired with EPI (echo-planar imaging) MR schemes.

The library is designed to provide an easily accessible, state-of-the-art interface that is robust to differences in scan acquisition protocols and that requires minimal user input.

This open-source neuroimaging data processing tool is being developed as a part of the MRI image analysis and reproducibility platform offered by NiPreps.

sdcflows's People

Contributors

alioco avatar anibalsolon avatar bpinsard avatar chrisgorgo avatar craigmoodie avatar dangom avatar dependabot[bot] avatar effigies avatar eilidhmacnicol avatar emdupre avatar feilong avatar hippocampusgirl avatar jdkent avatar kasbohm avatar kimsin98 avatar lalalavi avatar marcelzwiers avatar markushs avatar mattcieslak avatar mgxd avatar oesteban avatar rciric avatar romainvala avatar rwblair avatar sitek avatar smeisler avatar tsalo avatar yarikoptic avatar zenkavi avatar zhifangy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdcflows's Issues

Error during merging of fieldmaps with opposite phase encoding directions

Overview

Hello, I'm running fMRIPrep on 40 participants. In about 50% of my sample, there seems to be an issue when merging the fieldmaps with opposite phase encoding directions. Details are below. Please let me know if you need any additonal information. I'm looking into whether I would be able to share (parts of) the data to reproduce this error but maybe that is a known issue and a solution can easily be found. Thanks in advance for your help!

Error Node Name:

fmriprep_wf.single_subject_01_wf.func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf.sdc_wf.pepolar_unwarp_wf.prepare_epi_opposite_wf.merge

System specification

I'm running fMRIPrep on a Torque cluster environment using Singularity:

Operating system:

uname -v
poldracklab/fmriprep#1 SMP Debian 4.9.168-1+deb9u2 (2019-05-13)

Singularity version:

singularity --version
singularity version 3.1.1+ds

fMRIPrep version

singularity run fmriprep_latest.sif --version
fmriprep v1.5.0rc2

I used the bids-validator to verify that the dataset is BIDS-valid.

Command to run fMRIPrep

singularity run -B ${PATH_BIDS}:/input:ro \
	-B ${PATH_OUT}:/output:rw -B ${PATH_FMRIPREP}:/utilities:ro \
	-B ${PATH_WORK_SUB}:/work:rw ${PATH_CONTAINER} \
	--fs-license-file /utilities/fs_600_license.txt \
	/input/ /output/ participant --participant_label ${SUB_PAD} -w /work/ \
	--mem_mb ${MEM_MB} --nthreads ${N_CPUS} --omp-nthreads $N_THREADS \
	--write-graph --stop-on-first-crash \
	--output-spaces T1w MNI152NLin2009cAsym fsnative \
	--notrack --verbose --resource-monitor

Full error message

fMRIPrep failed: Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/plugins/multiproc.py", line 69, in run_node
    result['result'] = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 473, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 564, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 649, in _run_command
    result = self._interface.run(cwd=outdir)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/freesurfer/base.py", line 265, in run
    return super(FSCommandOpenMP, self).run(**inputs)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/freesurfer/base.py", line 144, in run
    return super(FSCommand, self).run(**inputs)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 376, in run
    runtime = self._run_interface(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 761, in _run_interface
    self.raise_exception(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 698, in raise_exception
    ).format(**runtime.dictcopy()))
RuntimeError: Command:
mri_robust_template --satit --fixtp --mov /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0001.nii.gz /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0002.nii.gz /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0003.nii.gz /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0004.nii.gz /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0005.nii.gz --inittp 1 --iscale --noit --template template.nii.gz --subsample 200
Standard output:
$Id: mri_robust_template.cpp,v 1.54 2016/05/05 21:17:08 mreuter Exp $

--satit: Will estimate SAT iteratively!
--fixtp: Will map everything to init TP!
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz as movable/source volume.
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0001.nii.gz as movable/source volume.
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0002.nii.gz as movable/source volume.
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0003.nii.gz as movable/source volume.
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0004.nii.gz as movable/source volume.
--mov: Using /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0005.nii.gz as movable/source volume.
    Total: 6 input volumes
--inittp: Using TP 1 as target for initialization
--iscale: Enableing intensity scaling!
--noit: Will output only first template (no iterations)!
--template: Using template.nii.gz as template output volume.
--subsample: Will subsample if size is larger than 200 on all axes!
Setting iscale ...
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz' to bspline ...
MRItoBSpline degree 3
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0001.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0001.nii.gz' to bspline ...
MRItoBSpline degree 3
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0002.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0002.nii.gz' to bspline ...
MRItoBSpline degree 3
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0003.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0003.nii.gz' to bspline ...
MRItoBSpline degree 3
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0004.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0004.nii.gz' to bspline ...
MRItoBSpline degree 3
reading source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0005.nii.gz'...
converting source '/work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0005.nii.gz' to bspline ...
MRItoBSpline degree 3

MultiRegistration::initializing Xforms (init 1 , maxres 0 , iterate 5 , epsit 0.01 ) : 

[init] ========================= TP 2 to TP 1 ==============================
         Register TP 2 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0001.nii.gz )
          to      TP 1 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz )


[init] ========================= TP 6 to TP 1 ==============================
         Register TP 6 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0005.nii.gz )
          to      TP 1 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz )


[init] ========================= TP 4 to TP 1 ==============================
         Register TP 4 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0003.nii.gz )
          to      TP 1 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz )


[init] ========================= TP 5 to TP 1 ==============================
         Register TP 5 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0004.nii.gz )
          to      TP 1 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz )


[init] ========================= TP 3 to TP 1 ==============================
         Register TP 3 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0002.nii.gz )
          to      TP 1 ( /work/fmriprep_wf/single_subject_01_wf/func_preproc_ses_01_task_highspeed_rec_prenorm_run_04_wf/sdc_wf/pepolar_unwarp_wf/prepare_epi_opposite_wf/split/mapflow/_split0/vol0000.nii.gz )


   - Max Resolution used: 
0
     -- gpS ( 96   - Max Resolution used: 0
 , 96 , 64 )

   - Max Resolution used: 0
     -- gpS ( 96 , 96 , 64 )
     -- gpT ( 96 , 96 , 64 )
     -- gpT (    - running loop to estimate saturation parameter:
96 , 96 , 64 )
   - running loop to estimate saturation parameter:
     -- gpS ( 96 , 96 , 64 )
     -- gpT ( 96 , 96 , 64 )
   - running loop to estimate saturation parameter:

   - Max Resolution used: 0
     -- gpS ( 96 , 96 , 64 )
     -- gpT ( 96 , 96 , 64 )
   - running loop to estimate saturation parameter:

   - Max Resolution used: 0
     -- gpS ( 96 , 96 , 64 )
     -- gpT ( 96 , 96 , 64 )
   - running loop to estimate saturation parameter:
Standard error:
MyMatrix.cpp: info = 4, something went wrong:
MyMatrix.cpp: the QR iteration failed, but the last 0 eigenvalues may be correct
mri_robust_template: MyMatrix.cpp:1807: static void MyMatrix::SchurComplex(const vnl_matrix<double>&, vnl_matrix<std::complex<double> >&, vnl_matrix<std::complex<double> >&): Assertion `info==0' failed.
Aborted (core dumped)
Return code: 134

Preprocessing did not finish successfully. Errors occurred while processing data from participants: 01 (1). Check the HTML reports for details.
/usr/local/miniconda/lib/python3.7/site-packages/scipy/fftpack/basic.py:160: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  z[index] = x
/usr/local/miniconda/lib/python3.7/site-packages/scipy/fftpack/basic.py:160: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  z[index] = x

Spiral fieldmap estimation workflow is broken

@poldrack just hit this wall

Node: fmriprep_wf.single_subject_s573_wf.func_preproc_ses_1_task_DPX_run_1_wf.sdc_estimate_wf.fmap_wf.fmapmrg
Working directory: /scratch1/01329/poldrack/uh2_workdir/fmriprep_wf/single_subject_s573_wf/func_preproc_ses_1_task_DPX_run_1_wf/sdc_estimate_wf/fmap_wf/fmapmrg

Node inputs:

hmc = False
in_files = ['/scratch1/01329/poldrack/BIDS_scans/sub-s573/ses-1/fmap/sub-s573_ses-1_fieldmap.nii.gz']
to_ras = True
zero_based_avg = False

Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/plugins/multiproc.py", line 69, in run_node
    result['result'] = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 479, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 585, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 678, in _run_command
    result = self._interface.run(cwd=outdir)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 382, in run
    runtime = self._run_interface(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/niworkflows/interfaces/images.py", line 83, in _run_interface
    hmcdat = hmcnii.get_fdata().mean(axis=3)
  File "/usr/local/miniconda/lib/python3.7/site-packages/numpy/core/_methods.py", line 62, in _mean
    rcount = _count_reduce_items(arr, axis)
  File "/usr/local/miniconda/lib/python3.7/site-packages/numpy/core/_methods.py", line 55, in _count_reduce_items
    items *= arr.shape[ax]
IndexError: tuple index out of range

The problem is that #52 resulted in a broken workflow for fieldmaps. I'm not sure whether this problem was inherited from the upstream PR I was based on or I introduced it. Regardless the cause, I'll be fixing this today and add one test for it.

EDIT: Actually a problem in NiWorkflows.

Support dynamic distortion correction with DOCMA

With complex-valued, multi-echo data (i.e., ME-EPI with both magnitude and phase information reconstructed), it is possible to estimate and correct for distortion on a volume-by-volume basis. I'm definitely not an expert in this area, but recently I've been reading a bit about it and there is a method called DOCMA that uses the phase data from the first two echoes to compute a phase-difference map and perform distortion correction on each volume of a time series, independently. The math definitely goes over my head, but it looks like the method is roughly equivalent to simply splitting the time series up into individual volumes and then performing standard distortion correction using the first two echoes as the field map. If that is the case, then I think this could be implemented fairly easily once #30 is merged.

Other methods for dynamic distortion correction that I've come across, including the UMPIRE multi-echo phase unwrapping method, seem to have special requirements, like uneven, highly specific echo times or alternating echo times for a single-echo protocol. DOCMA, on the other hand, seems to be applicable to any multi-echo sequence with phase information.

EDIT: After further investigation, I don't think the phasediff workflow will work as needed for dynamic distortion correction because the skullstripping performed in the workflow seems to be static (i.e., it treats 4D data as 3D and only produces one 3D mask). The whole procedure will probably require a splitting node wrapping around the workflow to separate all of the 4D datasets into 3D volumes before calculating and applying the field maps.

[limited FoV] ds000217 fieldmap issues

Poor skulls stripping of the magnitude image
image

Poor coregistration between magnitude and BOLD images
image

fieldmap corrections induces artefacts
image

sub-Exp1s02 all runs

[ENH] Add testing data

We can use https://openneuro.org/datasets/ds001600/versions/1.0.0 to get a pepolar, phasediff and 3 different versions of phase1/phase2. I'm checking on whether we can add a 4th version of phase1/phase2 from a 7T magnet (which is of course different from the other 3)

  • Create stand-alone archives containing one of each BIDS-compatible fieldmap type.
  • Upload somewhere public. UPenn Box or the osf server?
  • add to circleci download job

RuntimeError: EchoTime2 metadata field not found. Please consult the BIDS specification.

I am trying to run fmriprep the OpenNeuro published dataset (like https://openneuro.org/datasets/ds001454)

The fmap data on this dataset seems to be stored in non-BIDS compatible format, and fmriprep fails with the following error message.

fMRIPrep failed: Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/plugins/legacymultiproc.py", line 69, in run_node
    result['result'] = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 479, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 569, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 662, in _run_command
    result = self._interface.run(cwd=outdir)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 382, in run
    runtime = self._run_interface(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/sdcflows/interfaces/fmap.py", line 204, in _run_interface
    _delta_te(self.inputs.metadata),
  File "/usr/local/miniconda/lib/python3.7/site-packages/sdcflows/interfaces/fmap.py", line 529, in _delta_te
    'EchoTime2 metadata field not found. Please consult the BIDS specification.')
RuntimeError: EchoTime2 metadata field not found. Please consult the BIDS specification.

The EchoTime1/2 are basically stored under magnitude1.json and magnitude2.json respectively, and on phasediff.json, it just has "EchoTime" (from magnitude2). According to BIDS specification, EchoTime1/2 should be stored on phasediff.json, and there should be no magnitude1/2.json.

I think I can pursuit several options...

  1. Run fmriprep without fmap
  2. Download the dataset, modify the fmap json manually, and run fmriprep
  3. Have fmriprep updated so that it will look for magnitude1/2.json if EchoTime1/2 are not specified in the phasediff.json - although it's not BIDS compatible..
  4. OpenNeuro will run BIDS validator on older datasets and correct issues if it fails to validate?

What would you recommend me to do?

Invalid transformations for some Phase1/Phase2 fieldmaps

We encounter an error (log below) in phmap2rads that we have associated with a certain type of fieldmap acquisition but don't know why it fails. Specifically, the when the BOLD scan and the fieldmap scan are both acquired axially there is no error, but when the fieldmap is acquired sagitally the error happens. The error message below is followed by examples of fieldmaps that work and don't work.

========================

File: /DATA/fmriprep-1.5.5/fmriprep/sub-R/log/20200124-061243_5ea8ae31-a295-496d-a586-748a17830a8f/crash-20200124-062515-fmriprep-phmap2rads-2f64b28a-ad9b-497a-b4a0-1242888fad3c.txt

Working Directory: /DATA/fmriprep-1.5.5/work_sub-R/fmriprep_wf/single_subject_R_wf/func_preproc_ses_05_task_taskmotor_run_01_wf/sdc_estimate_wf/phdiff_wf/phmap2rads
Inputs:

    in_file: ['/DATA/fmriprep-1.5.5/bids/sub-R/ses-05/fmap/sub-R_ses-05_run-01_phasediff.nii.gz']

Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/plugins/multiproc.py", line 336, in _send_procs_to_workers
    self.procs[jobid].run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 516, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 1373, in _run_interface
    stop_first=str2bool(self.config["execution"]["stop_on_first_crash"]),
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 1295, in _collate_results
    "Subnodes of node: %s failed:\n%s" % (self.name, "\n".join(msg))
Exception: Subnodes of node: phmap2rads failed:
Subnode 0 failed
Error: Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/utils.py", line 94, in nodelist_runner
    result = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 516, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 635, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/pipeline/engine/nodes.py", line 741, in _run_command
    result = self._interface.run(cwd=outdir)
  File "/usr/local/miniconda/lib/python3.7/site-packages/nipype/interfaces/base/core.py", line 395, in run
    runtime = self._run_interface(runtime)
  File "/usr/local/miniconda/lib/python3.7/site-packages/sdcflows/interfaces/fmap.py", line 266, in _run_interface
    newpath=runtime.cwd)
  File "/usr/local/miniconda/lib/python3.7/site-packages/sdcflows/interfaces/fmap.py", line 673, in au2rads
    data[data < 0] = - np.pi * data[data < 0] / data[data < 0].min()
  File "/usr/local/miniconda/lib/python3.7/site-packages/numpy/core/_methods.py", line 32, in _amin
    return umr_minimum(a, axis, None, out, keepdims, initial)
ValueError: zero-size array to reduction operation minimum which has no identity

When creating this crashfile, the results file corresponding
to the node could not be found.

===================
A fieldmap acquisition that works has the following output from c3d -info:
Image #1: dim = [144, 144, 59]; bb = {[172.569 172.569 -78.3001], [522.569 522.569 80.9999]}; vox = [2.43056, 2.43056, 2.7]; range = [-250, 249.881]; orient = LPI

A fieldmap acquisition that producess the error above has the following output from c3d -info:
Image #1: dim = [59, 144, 144]; bb = {[78.3001 172.569 -172.569], [237.6 522.569 177.431]}; vox = [2.7, 2.43056, 2.43056]; range = [-250, 249.881]; orient = LPI

Very short TE EPIs and other adjustments of SDC-SyN

Here I suggested that, in situations like DS000148 where EPIs are acquired with very short TEs, it might be interesting not to invert the T1w image.

@effigies also suggested using T2w images whenever possible. I argued that in general I totally agree, but didn't see it clear for the particular case of very short TE EPIs.

Additionally, I suggested that, when we are running BBR after a successful SDC method (regardless which one) then the BBR should use only 6 dof. The rationale is that any affine/nonlinear deformation w.r.t. the T1 contours should have been captured by the SDC. Enabling 3 additional DoFs is asking for trouble plagiarizing the expression from Chris (even though he used it in a close but different context).

create fieldcoef image

I saw that fmriprep used to have a workflow for creating the fieldcoef files that are now supported by eddy. Do you know if that code still works? Should we add it to this repository?

PE-Polar SDC: Unify interface

Currently, two important inputs are passed by argument (bold_meta, and epi_fmaps) and the other three (in_reference, in_reference_brain, in_mask) are passed by Nipype workflow inputs.

All of them should be workflow inputs.

SDC: Unify unwarping workflows

After estimation of the displacements field map (either via phase1/2, phasediff, PE-polar, or SyN), the unwarping should happen with a unique workflow.

This requires #19.

Run fieldmapless distortion correction on its own

Hi all,
I'm trying to compare different ways to preprocess my data, and I'm wondering if it is possible to run only fieldmapless susceptibility distortion correction without all the other steps of fMRIprep? I'm hoping I can input an already skull stripped T1 file and a bold file and obtain a distortion corrected bold file (with a transformation matrix).

Also, would it be better to use an already motion corrected bold file, or the raw bold file?

Thanks!

-Kirk

SDC: phase1/2, phasediff and fieldmap should share a common final stage

Simplify this:

https://github.com/poldracklab/fmriprep/blob/9c57dded04c7c0f26768264afaaee1d4aa158b93/fmriprep/workflows/fieldmap/base.py#L202-L241

At this time, init_fmap_wf and init_phdiff_wf are very similar. The idea would be to implement:

  • Magnitude registration; and
  • regularization and displacements field calculation

only once on init_fmap_wf from a fieldmap in Hz. Phase1/2 and phasediff would then focus on phase unwrapping and conversion to Hz.

Stricter tests on fieldmap SDC

Some posts in neurostars and other private communications seem to point us to some unreliability of the current implementation of the fieldmap SDC.

SDC-pepolar: topup implementation

Follow-up on the suggestion in #10 to consider FSL topup as an alternative to 3dQwarp for estimating a displacement field from pairs of EPIs with opposite phase encoding directions.

I'm more than willing to help here, but could need some advice on how to transform the topup output into an ANTs-compatible warp field.

Possibly too BIDS-y?

I'm looking at the changes since the last release (0.1.1...master), and this stands out to me:

https://github.com/poldracklab/sdcflows/blob/a3a9978ec7e665eb278e53015f0a1c8902e563da/sdcflows/workflows/base.py#L144-L149

It looks like we're moving from passing a dictionary of fieldmaps and metadata to passing a PyBIDS BIDSFile object that provides access to these things.

I am concerned that we are tying the methods, which are general, too closely to a BIDS organizational scheme. While I think ingesting BIDS datasets is good, this tool will almost never be used in isolation, because you aren't generally going to want to susceptibility-correct non-motion-corrected files. From the perspective of benchmarking and making comparisons, too much BIDS integration may reduce flexibility, as well.

There's also a concern with relying on PyBIDS data structures like BIDSFile. From FitLins work, I can tell you that keeping in sync with the PyBIDS API can be difficult.

I think an interface or function to populate the available fieldmaps and metadata from BIDS is a good thing to provide, but I would think that it would be ideal if the actual workflows simply worked with nipype inputs and some vanilla Python data structures (e.g., dict).

Apologies for not bringing this up on the relevant PRs. I haven't been following this repo as closely as I should.

This is partly inspired by Neurostars #5207, which asks about the selection process as an isolable tool. By tying too closely to BIDS, we may be making this less usable in isolation.

remove enhance_and_skullstrip_bold from init_sdc_unwarp_wf?

I'm switching qsiprep to use sdcflows and was wondering how everyone would feel about removing the call to init_enhance_and_skullstrip_bold_wf from init_sdc_unwarp_wf. This function doesn't work well on b=0 images. If sdcflows is going to be modality-agnostic this would be very useful.

SDC-SyN: Improve handling the regularizing prior

Right now, distortions are constrained to the phase-encoding axis, but gradients are computed in all directions (and then the non-PE directions are dropped).

Improve the config of antsRegistration to compute and weight gradients only on the PE direction.

Paging @mattcieslak and @cookpa on this one too.

SDC: Leverage PyBIDS

The interface to all SDC methods would be much easier if they used pybids. This will particularly help with #18

Conform fieldmap images?

Question for FSL experts: is it worth conforming the fieldmap images to the same voxel orientation as the data that is to be corrected? I know FSL uses voxel coordinates for a lot of its algorithms so I'm concerned that not conforming the fieldmap images might cause problems. I have no evidence this is the case though.

SDC-pepolar implementation fails for some participants

Hi,

The SDC-pepolar implementation in fmriprep (1.3.1) has worked fine for most subjects in a dataset we are acquiring. However, for a few, typically older, participants we see very strange results. Interestingly, the spin-echo EPIs with opposing phase encoding (AP/PA) used to estimate fieldmaps also look somewhat strange in the failing participants.

Examples of SE EPIs in a subject that is handled well by fmriprep:
image

SDC results for this subject in fmriprep
image

Examples of SE EPIs in a subject that is not handled well by fmriprep:
image

And the resulting SDC output (note especially how anterior parts of lateral ventricle / corpus callosum get compressed; x = -17)
image

The reason I report this as an issue here (and not as an open question on neurostars) is because these subjects โ€“ with "non-prototypical" blip-up/blip-down-images โ€“ are handled well when using topup+applytopup to estimate and applying the fieldmap (i.e., the resulting distortion-corrected GRE EPIs align well with the structural scan).

Topup-estimated fieldmap from the second set of SE EPIs shown above (GRE EPI BOLD data with PE-direction AP to the left):
image

Distortion-corrected GRE EPI (applytopup) coregistered with structural T1w (WM-edge from FSL FAST overlaid). Same data as in the second SDC output shown above.
image

I'm wondering if this issue could be related to the limiting of displacement estimation to the target file phase encoding direction (as stated in the documentation for fmriprep.workflows.fieldmap.pepolar.init_pepolar_unwarp_wf). Clearly, in the second set of SE EPIs shown above, some displacements seem to go in the opposite direction of the phase encoding direction. Why this is happening for some subjects, I don't know, but as I wrote initially it seems to be the case mostly for older adults. I have verified that all scanner parameters and .json-info were correct for the relevant scans. Moreover, the "strange" PE-direction effects in some subjects seem to be stable across scanner sessions (we collect several fieldmaps over several days for these participants).

Thanks!
Markus

syn-sdc largely suboptimal results

I mentioned in Neurostars that the syn-sdc we get are not good. As suggested (I think by @effigies) I am posting a couple of examples here for your review.

Please note that my area of research focuses on basal ganglia (caudate and putamen more), so we focus a lot on the ventricles going into place after the correction.

These are cases where we have fieldmaps and compare fmb-sdc with syn-sdc figures. Since SVG files cannot be uploaded in github, I have added some screen recordings in the attached powerpoint file.

Syn-SDC_subptimal.pptx

We don't have a lot cases without fieldmaps, but looks like those without fieldmaps are a lost case, particularly from Philips scanners.

FSL FUGUE - Image Exception : #3 :: Attempted to divide images/ROIs of different sizes

Traceback (most recent call last):
  File "/usr/local/miniconda/bin/fmriprep", line 11, in <module>
    load_entry_point('fmriprep==1.0.8', 'console_scripts', 'fmriprep')()
  File "/usr/local/miniconda/lib/python3.6/site-packages/fmriprep/cli/run.py", line 267, in main
    fmriprep_wf.run(**plugin_settings)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/engine/workflows.py", line 602, in run
    runner.run(execgraph, updatehash=updatehash, config=self.config)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/plugins/base.py", line 168, in run
    self._clean_queue(jobid, graph, result=result))
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/plugins/base.py", line 227, in _clean_queue
    raise RuntimeError("".join(result['traceback']))
RuntimeError: Traceback (most recent call last):
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/plugins/multiproc.py", line 68, in run_node
    result['result'] = node.run(updatehash=updatehash)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/engine/nodes.py", line 487, in run
    result = self._run_interface(execute=True)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/engine/nodes.py", line 571, in _run_interface
    return self._run_command(execute)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/pipeline/engine/nodes.py", line 650, in _run_command
    result = self._interface.run(cwd=outdir)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/interfaces/base/core.py", line 516, in run
    runtime = self._run_interface(runtime)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/interfaces/base/core.py", line 1023, in _run_interface
    self.raise_exception(runtime)
  File "/usr/local/miniconda/lib/python3.6/site-packages/niworkflows/nipype/interfaces/base/core.py", line 960, in raise_exception
    ).format(**runtime.dictcopy()))
RuntimeError: Command:
fugue --despike --despikethreshold=2.1 --loadfmap=/root/src/fmriprep/work/fmriprep_wf/single_subject_ACTIGLIA011BL_wf/func_preproc_task_rest_wf/phdiff_wf/demean/sub-ACTIGLIA011BL_acq-rest_phasediff_rads_unwrapped_filt_demean.nii.gz --savefmap=sub-ACTIGLIA011BL_acq-rest_phasediff_rads_unwrapped_filt_demean_fieldmap.nii.gz --mask=/root/src/fmriprep/work/fmriprep_wf/single_subject_ACTIGLIA011BL_wf/func_preproc_task_rest_wf/phdiff_wf/bet/sub-ACTIGLIA011BL_acq-rest_magnitude1_ras_corrected_brain_mask.nii.gz
Standard output:

Standard error:
Image Exception : poldracklab/fmriprep#3 :: Attempted to divide images/ROIs of different sizes
terminate called after throwing an instance of 'RBD_COMMON::BaseException'
Aborted (core dumped)
Return code: 134

Susceptibility Distortion Correction - effective echo-spacing and total-readout time for Philips data

Dear all,

First, thank you for providing fmriprep - very useful!

I have questions about ESS and TRT for SDC of bold fMRI with a B0 fieldmap using Philips data.

In the documentation of fmriprep SDC and source code of fmriprep.interfaces.fmap there are the functions get_ees and get_trt. For Philips data it seems to be enough to define the WaterFatShift, MagneticFieldStrength, PhaseEncodingDirection and ParallelReductionFactorInPlane to calculate ess and trt.

First question:
a) does this signify that the EffectiveEchoSpacing does not need to be specified in the BIDS json file of the bold fmri, when WaterFatShift, MagneticFieldStrength, PhaseEncodingDirection and ParallelReductionFactorInPlane are given in the json file?
b) this then gives a warning in the bids-validation step ("You should define 'EffectiveEchoSpacing' for this file. If you don't provide this information field map correction will not be possible.") that can be safely ignored?

Second Question:
a) looking at the source code:

-
if wfs is not None:
        fstrength = in_meta['MagneticFieldStrength']
        wfd_ppm = 3.4  # water-fat diff in ppm
        g_ratio_mhz_t = 42.57  # gyromagnetic ratio for proton (1H) in MHz/T
        wfs_hz = fstrength * wfd_ppm * g_ratio_mhz_t
        return wfs / (wfs_hz * etl)
-

it seems that ParallelReductionFactorInPlane (the sense acceleration) is not used?

b) this ParallelReductionFactorInPlane is not used, since the echo-train-length (etl) in Philips images is already taking this into account? Correct?

c) I'm confused by other information on the web (among others: http://www.spinozacentre.nl/wiki/index.php/NeuroWiki:Current_developments#B0_correction) that also provide a calculation for the ESS as:
effective echo spacing = (((1000 * wfs)/(434.215 * (EPI factor+1))/acceleration)

Thus here 'acceleration' is used. Acceleration means the sense factor, which is also the same as the ParallelReductionFactorInPlane? Correct?
I guess it all depends on how 'etl' is defined. In the philips definition it already incorporates the ParallelReductionFactorInPlane (etl = NumberOfPhaseEncodingSteps/ParallelReductionFactorInPlane)

Last Question:

Starting from Philips dicom, I need to extract the correct information to put into the BIDS json file.

Using matlab dicominfo to extract relevant information out of Philips Dicom, one finds the following:

  • MagneticFieldStrength in 'MagneticFieldStrength'
  • etl in 'Private_2001_1013'
  • WaterFatShift in 'Private_2001_1022'
  • ParallelReductionFactorInPlane in 'Private_2005_140f.Item_1.ParallelReductionFactorInPlane';

EffectiveEchoSpacing is not in the philips dicom header, and is thus calculated.

Hope someone can help with (part of) my questions...

Best regards,

Stefan

Ps. Slightly of topic:

The PhaseEncodingDirection is not fully specified in the philips dicomheader? One cannot find e.g. 'j' or 'j-' as both are defined as 'COL' in the philips dicom header?
Also the slice timing info is not in the philips dicom header?
However ParallelReductionFactorOutOfPlane is specified in the philips dicom header, and this corresponds to the multiband factor?

Fieldmap correction

Dear fMRIprep experts,
We are using fmriprep 1.2.1, and the susceptibility correction was not properly applied for one subject, seemingly due to incorrect registration between fieldmap and T1 image. Despite the correct registration between EPI and T1, the final BOLD output is not in MNI space either.
Susceptibility distortion correction:
image
*_desc-brain_mask.nii.gz: (underlay is mni_icbm152_t1_tal_nlin_asym_09c.nii)
image
Our session had two identical functional runs, but the other run was not affected at all. I also checked the json files for EPI and fieldmap, and everything looks fine. I wonder if you have any suggestions to fix it.
Thank you,
Oliver

Cleaner edges when unwrapping with just extracted magnitude (no mask)

I do not understand the reason yet, but fieldmap edges are consistently cleaner when PRELUDE is ran without a mask.

The reason could be because PRELUDE expects either

  1. Original magnitude + mask
  2. Brain extracted magnitude

but the current workflow provides both.

As of now, the unwrapping sometimes has too much noise on edges that the edge cleaning postprocessing is not enough.

CI: pypi deployment failing

@effigies have you ever seen something like:

Processing ./dist/sdcflows-0.1.0.tar.gz
    ERROR: Complete output from command python setup.py egg_info:
    ERROR: Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-req-build-v9krq8c7/setup.py", line 26, in <module>
        main()
      File "/tmp/pip-req-build-v9krq8c7/setup.py", line 13, in main
        import versioneer
    ImportError: No module named 'versioneer'
    ----------------------------------------
ERROR: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-v9krq8c7/

SDC-SyN: Images with oblique xforms

As pointed out by @mattcieslak.

This issue can be closed with:

  • Replace the xforms with the corresponding matrix aligned with the imaging axes
  • Running SDC-SyN
  • Setting the original xforms on the displacements field (checking whether this produces the transform along the oblique axis).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.