|
| 1 | +# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- |
| 2 | +# vi: set ft=python sts=4 ts=4 sw=4 et: |
| 3 | + |
| 4 | +""" |
| 5 | +Nipype interface for seg_EM. |
| 6 | +
|
| 7 | +The em module provides higher-level interfaces to some of the operations |
| 8 | +that can be performed with the seg_em command-line program. |
| 9 | +
|
| 10 | +Examples |
| 11 | +-------- |
| 12 | +See the docstrings of the individual classes for examples. |
| 13 | +
|
| 14 | +Change directory to provide relative paths for doctests |
| 15 | + >>> import os |
| 16 | + >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) |
| 17 | + >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) |
| 18 | + >>> os.chdir(datadir) |
| 19 | +""" |
| 20 | + |
| 21 | +from ..base import (TraitedSpec, File, traits, CommandLineInputSpec, |
| 22 | + InputMultiPath) |
| 23 | +from .base import NiftySegCommand |
| 24 | +from ..niftyreg.base import get_custom_path |
| 25 | + |
| 26 | + |
| 27 | +class EMInputSpec(CommandLineInputSpec): |
| 28 | + """Input Spec for EM.""" |
| 29 | + in_file = File(argstr='-in %s', |
| 30 | + exists=True, |
| 31 | + mandatory=True, |
| 32 | + desc='Input image to segment', |
| 33 | + position=4) |
| 34 | + |
| 35 | + mask_file = File(argstr='-mask %s', |
| 36 | + exists=True, |
| 37 | + desc='Filename of the ROI for label fusion') |
| 38 | + |
| 39 | + # Priors |
| 40 | + no_prior = traits.Int(argstr='-nopriors %s', |
| 41 | + mandatory=True, |
| 42 | + desc='Number of classes to use without prior', |
| 43 | + xor=['prior_4D', 'priors']) |
| 44 | + |
| 45 | + prior_4D = File(argstr='-prior4D %s', |
| 46 | + exists=True, |
| 47 | + mandatory=True, |
| 48 | + desc='4D file containing the priors', |
| 49 | + xor=['no_prior', 'priors']) |
| 50 | + |
| 51 | + priors = InputMultiPath(argstr='%s', |
| 52 | + mandatory=True, |
| 53 | + desc='List of priors filepaths.', |
| 54 | + xor=['no_prior', 'prior_4D']) |
| 55 | + |
| 56 | + # iterations |
| 57 | + max_iter = traits.Int(argstr='-max_iter %s', default=100, |
| 58 | + desc='Maximum number of iterations') |
| 59 | + |
| 60 | + min_iter = traits.Int(argstr='-min_iter %s', default=0, |
| 61 | + desc='Minimun number of iterations') |
| 62 | + |
| 63 | + # other options |
| 64 | + bc_order_val = traits.Int(argstr='-bc_order %s', default=3, |
| 65 | + desc='Polynomial order for the bias field') |
| 66 | + |
| 67 | + mrf_beta_val = traits.Float(argstr='-mrf_beta %s', |
| 68 | + desc='Weight of the Markov Random Field') |
| 69 | + |
| 70 | + desc = 'Bias field correction will run only if the ratio of improvement \ |
| 71 | +is below bc_thresh. (default=0 [OFF])' |
| 72 | + bc_thresh_val = traits.Float(argstr='-bc_thresh %s', default=0, desc=desc) |
| 73 | + |
| 74 | + desc = 'Amount of regularization over the diagonal of the covariance \ |
| 75 | +matrix [above 1]' |
| 76 | + reg_val = traits.Float(argstr='-reg %s', desc=desc) |
| 77 | + |
| 78 | + desc = 'Outlier detection as in (Van Leemput TMI 2003). <fl1> is the \ |
| 79 | +Mahalanobis threshold [recommended between 3 and 7] <fl2> is a convergence \ |
| 80 | +ratio below which the outlier detection is going to be done [recommended 0.01]' |
| 81 | + outlier_val = traits.Tuple(traits.Float(), traits.Float(), |
| 82 | + argstr='-outlier %s %s', |
| 83 | + desc=desc) |
| 84 | + |
| 85 | + desc = 'Relax Priors [relaxation factor: 0<rf<1 (recommended=0.5), \ |
| 86 | +gaussian regularization: gstd>0 (recommended=2.0)] /only 3D/' |
| 87 | + relax_priors = traits.Tuple(traits.Float(), traits.Float(), |
| 88 | + argstr='-rf %s %s', |
| 89 | + desc=desc) |
| 90 | + |
| 91 | + # outputs |
| 92 | + out_file = File(name_source=['in_file'], |
| 93 | + name_template='%s_em.nii.gz', |
| 94 | + argstr='-out %s', |
| 95 | + desc='Output segmentation') |
| 96 | + out_bc_file = File(name_source=['in_file'], |
| 97 | + name_template='%s_bc_em.nii.gz', |
| 98 | + argstr='-bc_out %s', |
| 99 | + desc='Output bias corrected image') |
| 100 | + out_outlier_file = File(name_source=['in_file'], |
| 101 | + name_template='%s_outlier_em.nii.gz', |
| 102 | + argstr='-out_outlier %s', |
| 103 | + desc='Output outlierness image') |
| 104 | + |
| 105 | + |
| 106 | +class EMOutputSpec(TraitedSpec): |
| 107 | + """Output Spec for EM.""" |
| 108 | + out_file = File(desc="Output segmentation") |
| 109 | + out_bc_file = File(desc="Output bias corrected image") |
| 110 | + out_outlier_file = File(desc='Output outlierness image') |
| 111 | + |
| 112 | + |
| 113 | +class EM(NiftySegCommand): |
| 114 | + """Interface for executable seg_EM from NiftySeg platform. |
| 115 | +
|
| 116 | + seg_EM is a general purpose intensity based image segmentation tool. In |
| 117 | + it's simplest form, it takes in one 2D or 3D image and segments it in n |
| 118 | + classes. |
| 119 | +
|
| 120 | + For source code, see http://cmictig.cs.ucl.ac.uk/wiki/index.php/NiftySeg |
| 121 | + For Documentation, see: |
| 122 | + http://cmictig.cs.ucl.ac.uk/wiki/index.php/NiftySeg_documentation |
| 123 | +
|
| 124 | + Examples |
| 125 | + -------- |
| 126 | + >>> from nipype.interfaces import niftyseg |
| 127 | + >>> node = niftyseg.EM() |
| 128 | + >>> node.inputs.in_file = 'im1.nii' |
| 129 | + >>> node.inputs.no_prior = 4 |
| 130 | + >>> node.cmdline # doctest: +ALLOW_UNICODE |
| 131 | + 'seg_EM -in im1.nii -nopriors 4 -bc_out im1_bc_em.nii.gz \ |
| 132 | +-out im1_em.nii.gz -out_outlier im1_outlier_em.nii.gz' |
| 133 | +
|
| 134 | + """ |
| 135 | + _cmd = get_custom_path('seg_EM', env_dir='NIFTYSEGDIR') |
| 136 | + _suffix = '_em' |
| 137 | + input_spec = EMInputSpec |
| 138 | + output_spec = EMOutputSpec |
| 139 | + |
| 140 | + def _format_arg(self, opt, spec, val): |
| 141 | + """Convert input to appropriate format for seg_EM.""" |
| 142 | + if opt == 'priors': |
| 143 | + _nb_priors = len(self.inputs.priors) |
| 144 | + return '-priors %d %s' % (_nb_priors, ' '.join(self.inputs.priors)) |
| 145 | + else: |
| 146 | + return super(EM, self)._format_arg(opt, spec, val) |
0 commit comments