Skip to content
This repository was archived by the owner on Dec 27, 2022. It is now read-only.

Commit a93726f

Browse files
authored
Merge pull request #60 from josephmje/develop
enh/fix: add eddy_cuda and minor updates to pybids and eddy quad
2 parents 13b8f70 + dfc0b67 commit a93726f

File tree

6 files changed

+58
-31
lines changed

6 files changed

+58
-31
lines changed

README.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ You should have raw data organized in the BIDS format. Also, you should have run
3131
| |-- sub-01
3232
| |-- dwi
3333
| |-- sub-01_ses-01_dwi.nii.gz
34-
| |-- sub-01_ses-01_dwi.bvals
35-
| |-- sub-01_ses-01_dwi.bvecs
34+
| |-- sub-01_ses-01_dwi.bval
35+
| |-- sub-01_ses-01_dwi.bvec
3636
| |-- fmap
37-
| |-- sub-01_ses-01_dir-AP_dwi.nii.gz
38-
| |-- sub-01_ses-01_dir-PA_dwi.nii.gz
37+
| |-- sub-01_ses-01_acq-dwi_dir-AP_epi.nii.gz
38+
| |-- sub-01_ses-01_acq-dwi_dir-PA_epi.nii.gz
3939
| |-- derivatives
4040
| |-- sub-01
4141
| |-- freesurfer

dmriprep/cli.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# -*- coding: utf-8 -*-
22

33
"""Console script for dmriprep."""
4+
import os
45
import sys
6+
import warnings
7+
58
import click
6-
from . import run
9+
710
from . import io
11+
from . import run
812
from .data import get_dataset
9-
import os
10-
import warnings
1113

1214
# Filter warnings that are visible whenever you import another package that
1315
# was compiled against an older numpy than is installed.

dmriprep/io.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
BIDS-functions to return inputs for the run.py functions.
33
44
"""
5-
from glob import glob
65
import os
76
import os.path as op
7+
from glob import glob
8+
89
import bids
910

1011

@@ -20,18 +21,26 @@ def get_bids_subject_input_files(subject_id, bids_input_directory):
2021
subjects = layout.get_subjects()
2122
assert subject_id in subjects, "subject {} is not in the bids folder".format(subject_id)
2223

23-
ap_file = layout.get(subject=subject_id, fmap="epi", modality="fmap", dir="AP")
24+
ap_file = layout.get(subject=subject_id,
25+
datatype='fmap',
26+
suffix='epi',
27+
dir='AP',
28+
extensions=['.nii', '.nii.gz'])
2429
assert len(ap_file) == 1, 'found {} ap fieldmap files and we need just 1'.format(len(ap_file))
2530

26-
pa_file = layout.get(subject=subject_id, fmap="epi", modality="fmap", dir="PA")
31+
pa_file = layout.get(subject=subject_id,
32+
datatype='fmap',
33+
suffix='epi',
34+
dir='PA',
35+
extensions=['.nii', '.nii.gz'])
2736
assert len(pa_file) == 1, 'found {} pa fieldmap files and we need just 1'.format(len(pa_file))
2837

29-
dwi_files = layout.get(subject=subject_id, modality="dwi")
38+
dwi_files = layout.get(subject=subject_id, datatype='dwi', suffix='dwi')
3039
valid_dwi_files = []
3140

3241
for d in dwi_files:
33-
if d.filename.startswith(op.abspath(op.join(bids_input_directory, 'sub-' + subject_id))):
34-
valid_dwi_files.append(d.filename)
42+
if d.path.startswith(op.abspath(op.join(bids_input_directory, 'sub-' + subject_id))):
43+
valid_dwi_files.append(d.path)
3544

3645
dwi_file = [d for d in valid_dwi_files if d.endswith('.nii.gz') and not "TRACE" in d]
3746
assert len(dwi_file) == 1, 'found {} dwi files and we need just 1'.format(len(dwi_file))
@@ -51,8 +60,8 @@ def get_bids_subject_input_files(subject_id, bids_input_directory):
5160

5261
outputs = dict(subject_id="sub-"+subject_id,
5362
dwi_file=dwi_file[0],
54-
dwi_file_AP=ap_file[0].filename,
55-
dwi_file_PA=pa_file[0].filename,
63+
dwi_file_AP=ap_file[0].path,
64+
dwi_file_PA=pa_file[0].path,
5665
bvec_file=bvec_file[0],
5766
bval_file=bval_file[0],
5867
subjects_dir=op.abspath(subjects_dir))

dmriprep/qc.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import nibabel as nib
2-
import numpy as np
1+
import base64
32
import os.path as op
4-
from dipy.segment.mask import median_otsu
53
from io import BytesIO
6-
from nipype.utils.filemanip import save_json, load_json
7-
import base64
4+
85
import matplotlib
96
matplotlib.use('agg')
107
import matplotlib.pyplot as plt
8+
import nibabel as nib
9+
import numpy as np
10+
11+
from dipy.segment.mask import median_otsu
12+
from nipype.utils.filemanip import save_json, load_json
1113

1214

1315
def reorient_array(data, aff):

dmriprep/run.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import os.path as op
21
import os
2+
import os.path as op
33
from shutil import copyfile
44

55

@@ -363,6 +363,12 @@ def get_dmriprep_pe_workflow():
363363
eddy.inputs.residuals = True
364364
import multiprocessing
365365
eddy.inputs.num_threads = multiprocessing.cpu_count()
366+
import numba.cuda
367+
try:
368+
if numba.cuda.gpus:
369+
eddy.inputs.use_cuda = True
370+
except:
371+
eddy.inputs.use_cuda = False
366372

367373
topup = prep.get_node('peb_correction.topup')
368374
topup.inputs.checksize = True
@@ -374,12 +380,14 @@ def get_dmriprep_pe_workflow():
374380

375381
eddy_quad = pe.Node(fsl.EddyQuad(verbose=True, checksize=True), name="eddy_quad")
376382
get_path = lambda x: x.split('.nii.gz')[0].split('_fix')[0]
377-
wf.connect(prep, ('fsl_eddy.out_corrected', get_path), eddy_quad, "base_name")
383+
get_qc_path = lambda x: x.split('.nii.gz')[0] + '.qc'
384+
wf.connect(prep, ('fsl_eddy.out_corrected', get_path), eddy_quad, 'base_name')
378385
wf.connect(inputspec, 'bval_file', eddy_quad, 'bval_file')
379386
wf.connect(prep, 'Rotate_Bvec.out_file', eddy_quad, 'bvec_file')
380387
wf.connect(prep, 'peb_correction.topup.out_field', eddy_quad, 'field')
381388
wf.connect(prep, 'gen_index.out_file', eddy_quad, 'idx_file')
382389
wf.connect(prep, 'peb_correction.topup.out_enc_file', eddy_quad, 'param_file')
390+
wf.connect(prep, ('fsl_eddy.out_corrected', get_qc_path), eddy_quad, 'output_dir')
383391

384392
# need a mask file for eddy_quad. lets get it from the B0.
385393
def get_b0_mask_fn(b0_file):
@@ -396,7 +404,6 @@ def get_b0_mask_fn(b0_file):
396404
return mask_file
397405

398406

399-
400407
def id_outliers_fn(outlier_report, threshold, dwi_file):
401408
"""Get list of scans that exceed threshold for number of outliers
402409
@@ -596,6 +603,7 @@ def apply_transform_to_bvecs_fn(bvec_file, reg_mat_file):
596603
import numpy as np
597604
import nipype.utils.filemanip as fm
598605
import os
606+
599607
aff = np.loadtxt(reg_mat_file)
600608
bvecs = np.loadtxt(bvec_file)
601609
bvec_trans = []
@@ -654,6 +662,7 @@ def binarize_aparc(aparc_aseg):
654662
import nibabel as nib
655663
from nipype.utils.filemanip import fname_presuffix
656664
import os.path as op
665+
657666
img = nib.load(aparc_aseg)
658667
data, aff = img.get_data(), img.affine
659668
outfile = fname_presuffix(
@@ -746,13 +755,13 @@ def binarize_aparc(aparc_aseg):
746755
wf.connect(scale_tensor_eddy, "out_file", datasink, "dmriprep.dti_eddy.@scaled_tensor")
747756

748757
# all the eddy_quad stuff
749-
wf.connect(eddy_quad, 'out_qc_json', datasink, "dmriprep.qc.@eddyquad_json")
750-
wf.connect(eddy_quad, 'out_qc_pdf', datasink, "dmriprep.qc.@eddyquad_pdf")
751-
wf.connect(eddy_quad, 'out_avg_b_png', datasink, "dmriprep.qc.@eddyquad_bpng")
752-
wf.connect(eddy_quad, 'out_avg_b0_pe_png', datasink, "dmriprep.qc.@eddyquad_b0png")
753-
wf.connect(eddy_quad, 'out_cnr_png', datasink, "dmriprep.qc.@eddyquad_cnr")
754-
wf.connect(eddy_quad, 'out_vdm_png', datasink, "dmriprep.qc.@eddyquad_vdm")
755-
wf.connect(eddy_quad, 'out_residuals', datasink, 'dmriprep.qc.@eddyquad_resid')
758+
wf.connect(eddy_quad, 'qc_json', datasink, "dmriprep.qc.@eddyquad_json")
759+
wf.connect(eddy_quad, 'qc_pdf', datasink, "dmriprep.qc.@eddyquad_pdf")
760+
wf.connect(eddy_quad, 'avg_b_png', datasink, "dmriprep.qc.@eddyquad_bpng")
761+
wf.connect(eddy_quad, 'avg_b0_pe_png', datasink, "dmriprep.qc.@eddyquad_b0png")
762+
wf.connect(eddy_quad, 'cnr_png', datasink, "dmriprep.qc.@eddyquad_cnr")
763+
wf.connect(eddy_quad, 'vdm_png', datasink, "dmriprep.qc.@eddyquad_vdm")
764+
wf.connect(eddy_quad, 'residuals', datasink, 'dmriprep.qc.@eddyquad_resid')
756765

757766
# anatomical registration stuff
758767
wf.connect(bbreg, "min_cost_file", datasink, "dmriprep.reg.@mincost")
@@ -784,7 +793,7 @@ def report_fn(dwi_corrected_file, eddy_rms, eddy_report,
784793

785794
# for the report, lets show the eddy corrected (full volume) image
786795
wf.connect(voltransform, "transformed_file", report_node, 'dwi_corrected_file')
787-
wf.connect(eddy_quad, 'out_qc_json', report_node, 'eddy_qc_file')
796+
wf.connect(eddy_quad, 'qc_json', report_node, 'eddy_qc_file')
788797

789798
# add the rms movement output from eddy
790799
wf.connect(prep, "fsl_eddy.out_movement_rms", report_node, 'eddy_rms')
@@ -802,6 +811,7 @@ def report_fn(dwi_corrected_file, eddy_rms, eddy_report,
802811
# its super annoying.
803812
def name_files_nicely(dwi_file, subject_id):
804813
import os.path as op
814+
805815
dwi_fname = op.split(dwi_file)[1].split(".nii.gz")[0]
806816
substitutions = [
807817
("vol0000_flirt_merged.nii.gz", dwi_fname + '.nii.gz'),

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
'pandas',
2020
'parse',
2121
'tqdm',
22+
'pybids',
23+
'matplotlib',
24+
'cytoolz',
25+
'numba'
2226
]
2327

2428
setup_requirements = ['pytest-runner', ]

0 commit comments

Comments
 (0)