|
12 | 12 | from builtins import range, str
|
13 | 13 |
|
14 | 14 | import os
|
| 15 | +from ...external.due import BibTeX |
15 | 16 | from ...utils.filemanip import split_filename, copyfile
|
16 | 17 | from ..base import TraitedSpec, File, traits, InputMultiPath, OutputMultiPath, isdefined
|
17 | 18 | from .base import ANTSCommand, ANTSCommandInputSpec
|
@@ -1153,3 +1154,167 @@ def _list_outputs(self):
|
1153 | 1154 | self.inputs.out_atlas_voting_weight_name_format)
|
1154 | 1155 |
|
1155 | 1156 | return outputs
|
| 1157 | + |
| 1158 | + |
| 1159 | +class KellyKapowskiInputSpec(ANTSCommandInputSpec): |
| 1160 | + dimension = traits.Enum(3, 2, argstr='--image-dimensionality %d', |
| 1161 | + usedefault=True, |
| 1162 | + desc='image dimension (2 or 3)') |
| 1163 | + |
| 1164 | + segmentation_image = File(exists=True, argstr='--segmentation-image "%s"', |
| 1165 | + mandatory=True, |
| 1166 | + desc="A segmentation image must be supplied labeling the gray and white matters.\n" |
| 1167 | + "Default values = 2 and 3, respectively.",) |
| 1168 | + |
| 1169 | + gray_matter_label = traits.Int(2, usedefault=True, |
| 1170 | + desc="The label value for the gray matter label in the segmentation_image.") |
| 1171 | + |
| 1172 | + white_matter_label = traits.Int(3, usedefault=True, |
| 1173 | + desc="The label value for the white matter label in the segmentation_image.") |
| 1174 | + |
| 1175 | + gray_matter_prob_image = File(exists=True, argstr='--gray-matter-probability-image "%s"', |
| 1176 | + desc="In addition to the segmentation image, a gray matter probability image can be\n" |
| 1177 | + "used. If no such image is supplied, one is created using the segmentation image\n" |
| 1178 | + "and a variance of 1.0 mm.") |
| 1179 | + |
| 1180 | + white_matter_prob_image = File(exists=True, argstr='--white-matter-probability-image "%s"', |
| 1181 | + desc="In addition to the segmentation image, a white matter probability image can be\n" |
| 1182 | + "used. If no such image is supplied, one is created using the segmentation image\n" |
| 1183 | + "and a variance of 1.0 mm.") |
| 1184 | + |
| 1185 | + convergence = traits.Str(default="[50,0.001,10]", argstr='--convergence "%s"', usedefault=True, |
| 1186 | + desc="Convergence is determined by fitting a line to the normalized energy profile of\n" |
| 1187 | + "the last N iterations (where N is specified by the window size) and determining\n" |
| 1188 | + "the slope which is then compared with the convergence threshold.",) |
| 1189 | + |
| 1190 | + thickness_prior_estimate = traits.Float(10, usedefault=True, argstr="--thickness-prior-estimate %f", |
| 1191 | + desc="Provides a prior constraint on the final thickness measurement in mm.") |
| 1192 | + |
| 1193 | + thickness_prior_image = File(exists=True, argstr='--thickness-prior-image "%s"', |
| 1194 | + desc="An image containing spatially varying prior thickness values.") |
| 1195 | + |
| 1196 | + gradient_step = traits.Float(0.025, usedefault=True, argstr="--gradient-step %f", |
| 1197 | + desc="Gradient step size for the optimization.") |
| 1198 | + |
| 1199 | + smoothing_variance = traits.Float(1.0, argstr="--smoothing-variance %f", |
| 1200 | + desc="Defines the Gaussian smoothing of the hit and total images.") |
| 1201 | + |
| 1202 | + smoothing_velocity_field = traits.Float(1.5, argstr="--smoothing-velocity-field-parameter %f", |
| 1203 | + desc="Defines the Gaussian smoothing of the velocity field (default = 1.5).\n" |
| 1204 | + "If the b-spline smoothing option is chosen, then this defines the \n" |
| 1205 | + "isotropic mesh spacing for the smoothing spline (default = 15).") |
| 1206 | + |
| 1207 | + use_bspline_smoothing = traits.Bool(argstr="--use-bspline-smoothing 1", |
| 1208 | + desc="Sets the option for B-spline smoothing of the velocity field.") |
| 1209 | + |
| 1210 | + number_integration_points = traits.Int(10, argstr="--number-of-integration-points %d", |
| 1211 | + desc="Number of compositions of the diffeomorphism per iteration.") |
| 1212 | + |
| 1213 | + max_invert_displacement_field_iters = traits.Int(20, argstr="--maximum-number-of-invert-displacement-field-iterations %d", |
| 1214 | + desc="Maximum number of iterations for estimating the invert \n" |
| 1215 | + "displacement field.") |
| 1216 | + |
| 1217 | + cortical_thickness = File(argstr='--output "%s"', genfile=True, |
| 1218 | + desc='Filename for the cortical thickness.', hash_files=False) |
| 1219 | + |
| 1220 | + warped_white_matter = File(desc='Filename for the warped white matter file.', hash_files=False) |
| 1221 | + |
| 1222 | + |
| 1223 | +class KellyKapowskiOutputSpec(TraitedSpec): |
| 1224 | + cortical_thickness = File(desc="A thickness map defined in the segmented gray matter.") |
| 1225 | + warped_white_matter = File(desc="A warped white matter image.") |
| 1226 | + |
| 1227 | + |
| 1228 | +class KellyKapowski(ANTSCommand): |
| 1229 | + """ Nipype Interface to ANTs' KellyKapowski, also known as DiReCT. |
| 1230 | +
|
| 1231 | + DiReCT is a registration based estimate of cortical thickness. It was published |
| 1232 | + in S. R. Das, B. B. Avants, M. Grossman, and J. C. Gee, Registration based |
| 1233 | + cortical thickness measurement, Neuroimage 2009, 45:867--879. |
| 1234 | +
|
| 1235 | + Examples |
| 1236 | + -------- |
| 1237 | + >>> from pypes.interfaces.ants import KellyKapowski |
| 1238 | + >>> kk = KellyKapowski() |
| 1239 | + >>> kk.inputs.dimension = 3 |
| 1240 | + >>> kk.inputs.segmentation_image = "anat_hc_gm_wm.nii.gz" |
| 1241 | + >>> kk.inputs.gray_matter_prob_image = "anat_hc_gm.nii.gz" |
| 1242 | + >>> kk.inputs.white_matter_prob_image = "anat_hc_wm.nii.gz" |
| 1243 | + >>> kk.inputs.convergence = "[45,0.0,10]" |
| 1244 | + >>> kk.inputs.gradient_step = 0.025 |
| 1245 | + >>> kk.inputs.smoothing_variance = 1.0 |
| 1246 | + >>> kk.inputs.smoothing_velocity_field = 1.5 |
| 1247 | + >>> #kk.inputs.use_bspline_smoothing = False |
| 1248 | + >>> kk.inputs.number_integration_points = 10 |
| 1249 | + >>> kk.inputs.thickness_prior_estimate = 10 |
| 1250 | + >>> kk.cmdline # doctest: +ALLOW_UNICODE |
| 1251 | + 'KellyKapowski --convergence "[45,0.0,10]" |
| 1252 | + --output "[anat_hc_gm_wm_cortical_thickness.nii.gz, anat_hc_gm_wm_warped_white_matter.nii.gz]" |
| 1253 | + --image-dimensionality 3 --gradient-step 0.025000 --gray-matter-probability-image "anat_hc_gm.nii.gz" |
| 1254 | + --number-of-integration-points 10 --segmentation-image "[anat_hc_gm_wm.nii.gz,2,3]" --smoothing-variance 1.000000 |
| 1255 | + --smoothing-velocity-field-parameter 1.500000 --thickness-prior-estimate 10.000000 |
| 1256 | + --white-matter-probability-image "anat_hc_wm.nii.gz"' |
| 1257 | + """ |
| 1258 | + _cmd = "KellyKapowski" |
| 1259 | + input_spec = KellyKapowskiInputSpec |
| 1260 | + output_spec = KellyKapowskiOutputSpec |
| 1261 | + |
| 1262 | + references_ = [{'entry': BibTeX("@book{Das2009867," |
| 1263 | + "author={Sandhitsu R. Das and Brian B. Avants and Murray Grossman and James C. Gee}," |
| 1264 | + "title={Registration based cortical thickness measurement.}," |
| 1265 | + "journal={NeuroImage}," |
| 1266 | + "volume={45}," |
| 1267 | + "number={37}," |
| 1268 | + "pages={867--879}," |
| 1269 | + "year={2009}," |
| 1270 | + "issn={1053-8119}," |
| 1271 | + "url={http://www.sciencedirect.com/science/article/pii/S1053811908012780}," |
| 1272 | + "doi={http://dx.doi.org/10.1016/j.neuroimage.2008.12.016}" |
| 1273 | + "}"), |
| 1274 | + 'description': 'The details on the implementation of DiReCT.', |
| 1275 | + 'tags': ['implementation'], |
| 1276 | + }] |
| 1277 | + |
| 1278 | + def _parse_inputs(self, skip=None): |
| 1279 | + if skip is None: |
| 1280 | + skip = [] |
| 1281 | + skip += ['warped_white_matter', 'gray_matter_label', 'white_matter_label'] |
| 1282 | + return super(KellyKapowski, self)._parse_inputs(skip=skip) |
| 1283 | + |
| 1284 | + def _list_outputs(self): |
| 1285 | + outputs = self._outputs().get() |
| 1286 | + outputs['cortical_thickness'] = os.path.abspath(self._gen_filename('cortical_thickness')) |
| 1287 | + outputs['warped_white_matter'] = os.path.abspath(self._gen_filename('warped_white_matter')) |
| 1288 | + return outputs |
| 1289 | + |
| 1290 | + def _gen_filename(self, name): |
| 1291 | + if name == 'cortical_thickness': |
| 1292 | + output = self.inputs.cortical_thickness |
| 1293 | + if not isdefined(output): |
| 1294 | + _, name, ext = split_filename(self.inputs.segmentation_image) |
| 1295 | + output = name + '_cortical_thickness' + ext |
| 1296 | + return output |
| 1297 | + |
| 1298 | + if name == 'warped_white_matter': |
| 1299 | + output = self.inputs.warped_white_matter |
| 1300 | + if not isdefined(output): |
| 1301 | + _, name, ext = split_filename(self.inputs.segmentation_image) |
| 1302 | + output = name + '_warped_white_matter' + ext |
| 1303 | + return output |
| 1304 | + |
| 1305 | + return None |
| 1306 | + |
| 1307 | + def _format_arg(self, opt, spec, val): |
| 1308 | + if opt == "segmentation_image": |
| 1309 | + newval = '[{0},{1},{2}]'.format(self.inputs.segmentation_image, |
| 1310 | + self.inputs.gray_matter_label, |
| 1311 | + self.inputs.white_matter_label) |
| 1312 | + return spec.argstr % newval |
| 1313 | + |
| 1314 | + if opt == "cortical_thickness": |
| 1315 | + ct = self._gen_filename("cortical_thickness") |
| 1316 | + wm = self._gen_filename("warped_white_matter") |
| 1317 | + newval = '[{}, {}]'.format(ct, wm) |
| 1318 | + return spec.argstr % newval |
| 1319 | + |
| 1320 | + return super(KellyKapowski, self)._format_arg(opt, spec, val) |
0 commit comments