Skip to content

enh: add PETPVC wrapper #1335

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

Merged
merged 30 commits into from
Feb 4, 2016
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
34c7092
COMP: Fix runtime warning from ipython
hjmjohnson Sep 22, 2015
8e23884
STYLE: Avoid warning with divide by zero
hjmjohnson Sep 29, 2015
26cc84c
Added XOR to mkmask and source_file
Nov 30, 2015
51aa4f5
Include OAR-args
Jan 15, 2016
adefb22
Undo Commit
Jan 15, 2016
d15d89c
enh: add PETPVC wrapper
alexsavio Jan 28, 2016
2ed1624
improved AFNI version parsing after publication of 16.0.01, #1328
oesteban Jan 28, 2016
460b3a4
Add empty petpvc example files
alexsavio Jan 28, 2016
995ecaf
fix: drop example_data from petpvc
alexsavio Jan 28, 2016
2602cb6
Merge pull request #1337 from oesteban/fix/AfniVersionAfter16
oesteban Jan 28, 2016
b8f8e88
Merge pull request #1284 from srothmei/freesurfer_vol2surf_mkmask_xor
chrisgorgo Jan 31, 2016
e92aaa2
Merge branch 'master' into AvoidRuntimeWarningDivideByZero
chrisgorgo Jan 31, 2016
de946d2
Merge branch 'AvoidRuntimeWarningDivideByZero'
chrisgorgo Jan 31, 2016
74f8b78
Fixed bad conflict resolution
chrisgorgo Jan 31, 2016
463708c
fixed several errors
oesteban Jan 31, 2016
6be212e
fixed several errors
oesteban Jan 31, 2016
b73ec6d
make check-before-commit
oesteban Feb 1, 2016
360584d
enhance circle CI error reporting
chrisgorgo Feb 1, 2016
b0e5e29
merge oscars fixes + fix the sloppy merge
chrisgorgo Feb 1, 2016
69d6c78
further fixes
chrisgorgo Feb 1, 2016
6ee17d4
make FSL course download slightly easier to debug
chrisgorgo Feb 1, 2016
0e195b5
fixed mkdir
chrisgorgo Feb 1, 2016
1262955
Merge pull request #1338 from oesteban/fix/ProblemsInMaster
oesteban Feb 1, 2016
c1e811e
Merge pull request #1339 from chrisfilo/fix/sloppy_merge
chrisgorgo Feb 1, 2016
333122e
enh: add PETPVC wrapper
alexsavio Jan 28, 2016
248b38f
Add empty petpvc example files
alexsavio Jan 28, 2016
dbd86a8
fix: drop example_data from petpvc
alexsavio Jan 28, 2016
a45bd50
Merge branch 'petpvc' of github.com:alexsavio/nipype into petpvc
alexsavio Feb 2, 2016
435004c
add petpvc specs file
alexsavio Feb 2, 2016
a5a857f
fix non-ascii chars in petpvc.py
alexsavio Feb 3, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 235 additions & 0 deletions nipype/interfaces/petpvc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
Nipype interface for PETPVC.

PETPVC is a software from the Nuclear Medicine Department
of the UCL University Hospital, London, UK.

Its source code is here: https://github.com/UCL/PETPVC

The methods that it implement are explained here:
K. Erlandsson, I. Buvat, P. H. Pretorius, B. A. Thomas, and B. F. Hutton,
“A review of partial volume correction techniques for emission tomography
and their applications in neurology, cardiology and oncology,” Phys. Med.
Biol., vol. 57, no. 21, p. R119, 2012.

There is a publication waiting to be accepted for this software tool.


Its command line help shows this:

-i --input < filename >
= PET image file
-o --output < filename >
= Output file
[ -m --mask < filename > ]
= Mask image file
-p --pvc < keyword >
= Desired PVC method
-x < X >
= The full-width at half maximum in mm along x-axis
-y < Y >
= The full-width at half maximum in mm along y-axis
-z < Z >
= The full-width at half maximum in mm along z-axis
[ -d --debug ]
= Prints debug information
[ -n --iter [ Val ] ]
= Number of iterations
With: Val (Default = 10)
[ -k [ Val ] ]
= Number of deconvolution iterations
With: Val (Default = 10)
[ -a --alpha [ aval ] ]
= Alpha value
With: aval (Default = 1.5)
[ -s --stop [ stopval ] ]
= Stopping criterion
With: stopval (Default = 0.01)

----------------------------------------------
Technique - keyword

Geometric transfer matrix - "GTM"
Labbe approach - "LABBE"
Richardson-Lucy - "RL"
Van-Cittert - "VC"
Region-based voxel-wise correction - "RBV"
RBV with Labbe - "LABBE+RBV"
RBV with Van-Cittert - "RBV+VC"
RBV with Richardson-Lucy - "RBV+RL"
RBV with Labbe and Van-Cittert - "LABBE+RBV+VC"
RBV with Labbe and Richardson-Lucy- "LABBE+RBV+RL"
Multi-target correction - "MTC"
MTC with Labbe - "LABBE+MTC"
MTC with Van-Cittert - "MTC+VC"
MTC with Richardson-Lucy - "MTC+RL"
MTC with Labbe and Van-Cittert - "LABBE+MTC+VC"
MTC with Labbe and Richardson-Lucy- "LABBE+MTC+RL"
Iterative Yang - "IY"
Iterative Yang with Van-Cittert - "IY+VC"
Iterative Yang with Richardson-Lucy - "IY+RL"
Muller Gartner - "MG"
Muller Gartner with Van-Cittert - "MG+VC"
Muller Gartner with Richardson-Lucy - "MG+RL"

"""
from __future__ import print_function
from __future__ import division

import os
import warnings

from nipype.interfaces.base import (
TraitedSpec,
CommandLineInputSpec,
CommandLine,
File,
isdefined,
traits,
)

warn = warnings.warn

pvc_methods = ['GTM',
'IY',
'IY+RL',
'IY+VC',
'LABBE',
'LABBE+MTC',
'LABBE+MTC+RL',
'LABBE+MTC+VC',
'LABBE+RBV',
'LABBE+RBV+RL',
'LABBE+RBV+VC',
'MG',
'MG+RL',
'MG+VC',
'MTC',
'MTC+RL',
'MTC+VC',
'RBV',
'RBV+RL',
'RBV+VC',
'RL',
'VC']


class PETPVCInputSpec(CommandLineInputSpec):
in_file = File(desc="PET image file", exists=True, mandatory=True, argstr="-i %s")
out_file = File(desc="Output file", genfile=True, hash_files=False, argstr="-o %s")
mask_file = File(desc="Mask image file", exists=True, mandatory=True, argstr="-m %s")
pvc = traits.Enum(pvc_methods, desc="Desired PVC method", mandatory=True, argstr="-p %s")
fwhm_x = traits.Float(desc="The full-width at half maximum in mm along x-axis", mandatory=True, argstr="-x %.4f")
fwhm_y = traits.Float(desc="The full-width at half maximum in mm along y-axis", mandatory=True, argstr="-y %.4f")
fwhm_z = traits.Float(desc="The full-width at half maximum in mm along z-axis", mandatory=True, argstr="-z %.4f")
debug = traits.Bool (desc="Prints debug information", usedefault=True, default_value=False, argstr="-d")
n_iter = traits.Int (desc="Number of iterations", default_value=10, argstr="-n %d")
n_deconv = traits.Int (desc="Number of deconvolution iterations", default_value=10, argstr="-k %d")
alpha = traits.Float(desc="Alpha value", default_value=1.5, argstr="-a %.4f")
stop_crit = traits.Float(desc="Stopping criterion", default_value=0.01, argstr="-a %.4f")


class PETPVCOutputSpec(TraitedSpec):
out_file = File(desc = "Output file")


class PETPVC(CommandLine):
""" Use PETPVC for partial volume correction of PET images.

Examples
--------
>>> from ..testing import example_data
>>> #TODO get data for PETPVC
>>> pvc = PETPVC()
>>> pvc.inputs.in_file = example_data('pet.nii.gz')
Copy link
Member

Choose a reason for hiding this comment

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

after adding the docstring in the beginning of the file as I described in my other comment you can drop the example_data and just do pet.nii.gz

>>> pvc.inputs.mask_file = example_data('tissues.nii.gz')
>>> pvc.inputs.out_file = 'pet_pvc_rbv.nii.gz'
>>> pvc.inputs.pvc = 'RBV'
>>> pvc.inputs.fwhm_x = 2.0
>>> pvc.inputs.fwhm_y = 2.0
>>> pvc.inputs.fwhm_z = 2.0
>>> outs = pvc.run() #doctest: +SKIP
"""
input_spec = PETPVCInputSpec
output_spec = PETPVCOutputSpec
_cmd = 'petpvc'

def _list_outputs(self):
outputs = self.output_spec().get()
outputs['out_file'] = self.inputs.out_file
if not isdefined(outputs['out_file']):
method_name = self.inputs.pvc.lower()
outputs['out_file'] = self._gen_fname(self.inputs.in_file,
suffix='_{}_pvc'.format(method_name))

outputs['out_file'] = os.path.abspath(outputs['out_file'])
return outputs

def _gen_fname(self, basename, cwd=None, suffix=None, change_ext=True,
ext='.nii.gz'):
"""Generate a filename based on the given parameters.

The filename will take the form: cwd/basename<suffix><ext>.
If change_ext is True, it will use the extentions specified in
<instance>intputs.output_type.

Parameters
----------
basename : str
Filename to base the new filename on.
cwd : str
Path to prefix to the new filename. (default is os.getcwd())
suffix : str
Suffix to add to the `basename`. (defaults is '' )
change_ext : bool
Flag to change the filename extension to the given `ext`.
(Default is False)

Returns
-------
fname : str
New filename based on given parameters.

"""
from nipype.utils.filemanip import fname_presuffix

if basename == '':
msg = 'Unable to generate filename for command %s. ' % self.cmd
msg += 'basename is not set!'
raise ValueError(msg)
if cwd is None:
cwd = os.getcwd()
if change_ext:
if suffix:
suffix = ''.join((suffix, ext))
else:
suffix = ext
if suffix is None:
suffix = ''
fname = fname_presuffix(basename, suffix=suffix,
use_ext=False, newpath=cwd)
return fname

def _gen_filename(self, name):
if name == 'out_file':
return self._list_outputs()['out_file']
return None


if __name__ == '__main__':
Copy link
Member

Choose a reason for hiding this comment

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

no need for a main_- docstring example will be run by tests


#from .testing import example_data
#TODO get data for PETPVC

pvc = PETPVC()
pvc.inputs.in_file = example_data('pet.nii.gz')
pvc.inputs.mask_file = example_data('tissues.nii.gz')
pvc.inputs.out_file = 'pet_pvc_rbv.nii.gz'
pvc.inputs.pvc = 'RBV'
pvc.inputs.fwhm_x = 2.0
pvc.inputs.fwhm_y = 2.0
pvc.inputs.fwhm_z = 2.0
pvc.run()