Skip to content
Snippets Groups Projects
Commit dec4385d authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

dicom module checks to see that dcm2niix is present and recent

parent 8ca9e9ca
No related branches found
No related tags found
No related merge requests found
...@@ -14,6 +14,7 @@ wrappers around functionality provided by Chris Rorden's ``dcm2niix`` program: ...@@ -14,6 +14,7 @@ wrappers around functionality provided by Chris Rorden's ``dcm2niix`` program:
.. autosummary:: .. autosummary::
:nosignatures: :nosignatures:
enabled
scanDir scanDir
loadSeries loadSeries
...@@ -26,15 +27,21 @@ wrappers around functionality provided by Chris Rorden's ``dcm2niix`` program: ...@@ -26,15 +27,21 @@ wrappers around functionality provided by Chris Rorden's ``dcm2niix`` program:
import os.path as op import os.path as op
import subprocess as sp import subprocess as sp
import re
import glob import glob
import json import json
import logging
import nibabel as nib import nibabel as nib
import fsl.utils.tempdir as tempdir import fsl.utils.tempdir as tempdir
import fsl.utils.memoize as memoize
import fsl.data.image as fslimage import fsl.data.image as fslimage
log = logging.getLogger(__name__)
class DicomImage(fslimage.Image): class DicomImage(fslimage.Image):
"""The ``DicomImage`` is a volumetric :class:`.Image` with some associated """The ``DicomImage`` is a volumetric :class:`.Image` with some associated
DICOM metadata. DICOM metadata.
...@@ -80,6 +87,56 @@ class DicomImage(fslimage.Image): ...@@ -80,6 +87,56 @@ class DicomImage(fslimage.Image):
return self.__meta.get(*args, **kwargs) return self.__meta.get(*args, **kwargs)
@memoize.memoize
def enabled():
"""Returns ``True`` if ``dcm2niix`` is present, and recent enough,
``False`` otherwise.
"""
cmd = 'dcm2niix -h'
minimumVersion = (1, 0, 2016, 9, 30)
versionPattern = re.compile('v'
'(?P<major>[0-9]+)\.'
'(?P<minor>[0-9]+)\.'
'(?P<year>[0-9]{4})'
'(?P<month>[0-9]{2})'
'(?P<day>[0-9]{2})')
try:
output = sp.check_output(cmd.split()).decode()
output = [l for l in output.split('\n') if 'version' in l.lower()]
output = '\n'.join(output).split()
for word in output:
match = re.match(versionPattern, word)
if match is None:
continue
installedVersion = (
int(match.group('major')),
int(match.group('minor')),
int(match.group('year')),
int(match.group('month')),
int(match.group('day')))
# make sure installed version
# is equal to or newer than
# minimum required version
for iv, mv in zip(installedVersion, minimumVersion):
if iv > mv: return True
elif iv < mv: return False
# if we get here, versions are equal
return True
except Exception as e:
log.debug('Error parsing dcm2niix version string: {}'.format(e))
return False
def scanDir(dcmdir): def scanDir(dcmdir):
"""Uses ``dcm2niix`` to scans the given DICOM directory, and returns a """Uses ``dcm2niix`` to scans the given DICOM directory, and returns a
list of dictionaries, one for each data series that was identified. list of dictionaries, one for each data series that was identified.
...@@ -91,6 +148,9 @@ def scanDir(dcmdir): ...@@ -91,6 +148,9 @@ def scanDir(dcmdir):
one DICOM data series. one DICOM data series.
""" """
if not enabled():
raise RuntimeError('dcm2niix is not available or is too old')
dcmdir = op.abspath(dcmdir) dcmdir = op.abspath(dcmdir)
cmd = 'dcm2niix -b o -ba n -f %s -o . {}'.format(dcmdir) cmd = 'dcm2niix -b o -ba n -f %s -o . {}'.format(dcmdir)
...@@ -130,6 +190,9 @@ def loadSeries(series): ...@@ -130,6 +190,9 @@ def loadSeries(series):
:returns: List containing one or more :class:`.DicomImage` objects. :returns: List containing one or more :class:`.DicomImage` objects.
""" """
if not enabled():
raise RuntimeError('dcm2niix is not available or is too old')
dcmdir = series['DicomDir'] dcmdir = series['DicomDir']
snum = series['SeriesNumber'] snum = series['SeriesNumber']
desc = series['SeriesDescription'] desc = series['SeriesDescription']
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment