Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dwi preprocessing using metadata #15

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ ENV PATH /opt/freesurfer/bin:/opt/freesurfer/fsfast/bin:/opt/freesurfer/tktools:
# Install FSL 5.0.9
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
curl -sSL http://neuro.debian.net/lists/xenial.us-ca.full >> /etc/apt/sources.list.d/neurodebian.sources.list && \
curl -sSL http://neuro.debian.net/lists/trusty.us-ca.full >> /etc/apt/sources.list.d/neurodebian.sources.list && \
apt-key adv --recv-keys --keyserver hkp://pgp.mit.edu:80 0xA5D32F012649A5A9 && \
apt-get update && \
apt-get install -y fsl-core=5.0.9-1~nd+1+nd16.04+1 && \
Copy link
Contributor

Choose a reason for hiding this comment

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

are those changes still necessary applicable to this PR? (applies to connectome-workbench as well)

Expand Down
22 changes: 14 additions & 8 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def run_diffusion_processsing(**args):
'fMRISurface', 'DiffusionPreprocessing'],
default=['PreFreeSurfer', 'FreeSurfer', 'PostFreeSurfer',
'fMRIVolume', 'fMRISurface',
'DiffusionPreprocessing', 'TaskfMRIAnalysis'])
'DiffusionPreprocessing'])
parser.add_argument('--license_key', help='FreeSurfer license key - letters and numbers after "*" in the email you received after registration. To register (for free) visit https://surfer.nmr.mgh.harvard.edu/registration.html',
required=True)
parser.add_argument('-v', '--version', action='version',
Expand Down Expand Up @@ -426,18 +426,21 @@ def run_diffusion_processsing(**args):
onerun= True
numruns = {'run-01'}
if numruns:
for session in numruns:
for numrun in numruns:
if not onerun:
bvals = [f.filename for f in layout.get(subject=subject_label,
type='dwi', run=session,
type='dwi', run=numrun,
extensions=["bval"])]
else:
bvals = [f.filename for f in layout.get(subject=subject_label,
type='dwi', extensions=["bval"])]
## find number of directions by reading bval files, then create dictionary with corresponding
# bval file name, number of directions, dwi image file name, and phase encoding direction (i or j).
dwi_dict = {'bvalFile':[], 'bval':[], 'dwiFile':[], 'direction':[]}
for bvalfile in bvals:
with open(bvalfile) as f: # get number of directions
for bvalfile in bvals: # find number of directions
with open(bvalfile) as f:
bvalues = [bvalue for line in f for bvalue in line.split()]
# fill in the rest of dictionary
dwi_dict['bvalFile'].append(bvalfile)
dwi_dict['bval'].append(len(bvalues) - 1)
dwiFile = glob(os.path.join(os.path.dirname(bvalfile),'{0}.nii*'.format(os.path.basename(bvalfile).split('.')[0]))) # ensures bval file has same name as dwi file
Expand All @@ -447,15 +450,18 @@ def run_diffusion_processsing(**args):

# check if length of lists in dictionary are the same
n = len(dwi_dict['bvalFile'])
assert all(len(dwi_dict[k]) for k,v in dwi_dict.items())
assert all(len(dwi_dict[k]) == n for k,v in dwi_dict.items())

for dirnum in set(dwi_dict['bval']):
## the following statement extracts index values in dwi_dict['bval'] if the value matches
# "dirnum", which is the number of directions (i.e. 98 or 99). These index values are used
# to find the corresponding PE directions, dwi file names, etc. in the dictionary
idxs = { i for k,v in dwi_dict.iteritems() for i in range(0,len(dwi_dict['bval'])) if v[i] == dirnum }
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a comment explaining what this line does?

Copy link
Author

Choose a reason for hiding this comment

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

Line 450: I made a mistake - it's supposed to be
assert all(len(dwi_dict[k]) ==n for k,v in dwi_dict.items())

Line 453: extracts the index values in dwi_dict['bval'] if the value matches "dirnum", which is the number of directions (i.e. 98 or 99). These index values gets used to find the PE directions, dwi files names, etc. in the dictionary.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you could add this comment to the code it would be easier for people in the future to understand this code. Thanks!

Copy link
Author

Choose a reason for hiding this comment

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

Of course!

PEdirNums = set([dwi_dict['direction'][i] for i in idxs])
for PEdirNum in PEdirNums:
dwis = [ dwi_dict['dwiFile'][i] for i in idxs if dwi_dict['direction'][i] == PEdirNum ]
assert len(dwis) <= 2
dwiname = "Diffusion" + "_dir-" + str(dirnum) + "_" + session + "_corr_" + str(PEdirNum)
dwiname = "Diffusion" + "_dir-" + str(dirnum) + "_" + numrun + "_corr_" + str(PEdirNum)
if "j" in PEdirNum:
PEdir = 2
elif "i" in PEdirNum:
Expand Down Expand Up @@ -485,6 +491,6 @@ def run_diffusion_processsing(**args):
for stage, stage_func in dwi_stage_dict.iteritems():
if stage in args.stages:
stage_func()
except:
except NameError:
print("You may have missing diffusion data in the positive phase encoding direction.")
Copy link
Contributor

Choose a reason for hiding this comment

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

This tra/except statement still encompases a huge chunk of code that could produce "NameError" that does not necessarily mean that there is missing diffusion data in the positive phase encoding direction. This should be made more specific. Furthermore we should exit with a non zero code to indicate that something did not work correctly.