nipreps / sdcflows Goto Github PK
View Code? Open in Web Editor NEWSusceptibility Distortion Correction (SDC) workflows for EPI MR schemes
Home Page: https://www.nipreps.org/sdcflows
License: Apache License 2.0
Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes
Home Page: https://www.nipreps.org/sdcflows
License: Apache License 2.0
I'm looking at the changes since the last release (0.1.1...master), and this stands out to me:
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.
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
Voices against moving this project away from the poldracklab organization?
As per nipreps/fmriprep#1489 (comment), we need to make sure whether it is okay not to take in-plane acceleration into account here:
Also consider nipreps/fmriprep#1029 (comment)
As @Aksoo pointed out in nipreps/fmriprep#1886 (comment), this extrapolation should happen only along the PE-axis.
This issue is a reminder to check that end, until we have a better solution (#14).
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.
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).
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:
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?
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.
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.
@zenkavi this happened with your dataset:
Although it doesn't really seem to affect registration to the BOLD reference, we want to get this mask right 100% of the times.
Comes from nipreps/fmriprep#1493 (comment)
Although mistakenly described as such in the docstring, current init_sdc_unwarp_wf
implementation works on fieldmaps given in Hz. It should take displacements fields.
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:
*_desc-brain_mask.nii.gz: (underlay is mni_icbm152_t1_tal_nlin_asym_09c.nii)
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
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...
What would you recommend me to do?
Some posts in neurostars and other private communications seem to point us to some unreliability of the current implementation of the fieldmap SDC.
Calculate a new fieldmap average pooling datasets from OpenNeuro that have either fieldmaps or PEPOLAR acquisitions.
The fieldmap average should NOT be masked within the brain.
Then, upload the average to TemplateFlow and remove the old atlas.
If we plan on migrating the image host from r/poldracklab/sdcflows
to r/nipreps/sdcflows
, we'll have to extend / change circle's permissions.
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
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.
Follow the conversation that started around here #30 (comment).
Not really an issue, but I noticed this repository isn't using docker load
and docker save
like fmriprep does on circleci. Have you noticed an improvement in CI run times? Would your local registry method work for much larger images?
Based on the foundations set by nipreps/fmriprep#1359, finish up the phase1/2 implementation.
@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.
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)
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
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.
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.
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.
A better approach would be to check for PE direction when needed, and, if missing, print a warning and disable fieldmaps.
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!
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
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.
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
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
Simplify this:
At this time, init_fmap_wf
and init_phdiff_wf
are very similar. The idea would be to implement:
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.
@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/
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.
FreeSurfer is a heavy dependency and we are just using it for mri_robust_template
here:
The idea would be to replace that with ANTs' tools.
Since this is just a validation warning, fMRIPrep crashes in a quite obscure way (an interface missing the input).
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?
I'm finding for some older phase1/phase2 fieldmaps that it's necessary to set the kernel size to 5 for this node: https://github.com/poldracklab/sdcflows/blob/0.0.2/sdcflows/workflows/phdiff.py#L98
Is there a downside to setting the default to 5? Or should we make this a parameter?
To help implement nipreps/fmriprep#1653, aim at a simpler interface and minimize the massaging of inputs that is currently necessary.
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
The interface to all SDC methods would be much easier if they used pybids. This will particularly help with #18
As pointed out by @mattcieslak.
This issue can be closed with:
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.
We don't have a lot cases without fieldmaps, but looks like those without fieldmaps are a lost case, particularly from Philips scanners.
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:
SDC results for this subject in fmriprep
Examples of SE EPIs in a subject that is not handled well by fmriprep:
And the resulting SDC output (note especially how anterior parts of lateral ventricle / corpus callosum get compressed; x = -17)
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):
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.
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
Would it make sense to add the SDC warp in the derivatives for each unwarped image? At the moment we are saving the entire working directory to keep them. They're also not included in the h5 transform to the template because they differ for each scan. What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.