1
+ # -*- coding: utf-8 -*-
2
+ # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3
+ # vi: set ft=python sts=4 ts=4 sw=4 et:
4
+ """This module provides interfaces for workbench surface commands"""
5
+ from __future__ import (print_function , division , unicode_literals ,
6
+ absolute_import )
7
+ import os
8
+
9
+ from ..base import (TraitedSpec , File , traits , InputMultiObject ,
10
+ CommandLineInputSpec )
11
+ from .base import WBCommand
12
+ from ... import logging
13
+
14
+ iflogger = logging .getLogger ('interface' )
15
+
16
+ class MetricResampleInputSpec (CommandLineInputSpec ):
17
+ in_file = File (
18
+ exists = True ,
19
+ mandatory = True ,
20
+ argstr = "%s" ,
21
+ position = 0 ,
22
+ desc = "The metric file to resample" )
23
+ current_sphere = File (
24
+ exists = True ,
25
+ mandatory = True ,
26
+ argstr = "%s" ,
27
+ position = 1 ,
28
+ desc = "A sphere surface with the mesh that the metric is currently on" )
29
+ new_sphere = File (
30
+ exists = True ,
31
+ mandatory = True ,
32
+ argstr = "%s" ,
33
+ position = 2 ,
34
+ desc = ("A sphere surface that is in register with <current-sphere> and"
35
+ " has the desired output mesh" ))
36
+ method = traits .Enum (
37
+ "ADAP_BARY_AREA" ,
38
+ "BARYCENTRIC" ,
39
+ argstr = "%s" ,
40
+ mandatory = True ,
41
+ position = 3 ,
42
+ desc = ("The method name - ADAP_BARY_AREA method is recommended for"
43
+ " ordinary metric data, because it should use all data while"
44
+ " downsampling, unlike BARYCENTRIC. If ADAP_BARY_AREA is used,"
45
+ " exactly one of area_surfs or area_metrics must be specified" ))
46
+ metric_out = File (
47
+ name_source = ["new_sphere" ],
48
+ name_template = "%s.out" ,
49
+ keep_extension = True ,
50
+ argstr = "%s" ,
51
+ position = 4 ,
52
+ desc = "The output metric" )
53
+ area_surfs = traits .Bool (
54
+ position = 5 ,
55
+ argstr = "-area-surfs" ,
56
+ xor = ["area_metrics" ],
57
+ desc = "Specify surfaces to do vertex area correction based on" )
58
+ area_metrics = traits .Bool (
59
+ position = 5 ,
60
+ argstr = "-area-metrics" ,
61
+ xor = ["area_surfs" ],
62
+ desc = "Specify vertex area metrics to do area correction based on" )
63
+ current_area = File (
64
+ exists = True ,
65
+ position = 6 ,
66
+ argstr = "%s" ,
67
+ desc = ("A relevant anatomical surface with <current-sphere> mesh OR"
68
+ " a metric file with vertex areas for <current-sphere> mesh" ))
69
+ new_area = File (
70
+ exists = True ,
71
+ position = 7 ,
72
+ argstr = "%s" ,
73
+ desc = ("A relevant anatomical surface with <current-sphere> mesh OR"
74
+ " a metric file with vertex areas for <current-sphere> mesh" ))
75
+ roi_metric = File (
76
+ exists = True ,
77
+ position = 8 ,
78
+ argstr = "-current-roi %s" ,
79
+ desc = "Input roi on the current mesh used to exclude non-data vertices" )
80
+ valid_roi_out = traits .Bool (
81
+ position = 9 ,
82
+ argstr = "-valid-roi-out" ,
83
+ desc = "Output the ROI of vertices that got data from valid source vertices" )
84
+ largest = traits .Bool (
85
+ position = 10 ,
86
+ argstr = "-largest" ,
87
+ desc = "Use only the value of the vertex with the largest weight" )
88
+
89
+
90
+ class MetricResampleOutputSpec (TraitedSpec ):
91
+ out_file = File (exists = True , desc = "the output metric" )
92
+ roi_file = File (desc = "ROI of vertices that got data from valid source vertices" )
93
+
94
+
95
+ class MetricResample (WBCommand ):
96
+ """
97
+ Resample a metric file to a different mesh
98
+
99
+ >>> from nipype.interfaces.workbench import MetricResample
100
+ >>> metres = MetricResample()
101
+ >>> metres.inputs.in_file = 'sub-01_task-rest_bold_space-fsaverage5.L.func.gii'
102
+ >>> metres.inputs.method = 'ADAP_BARY_AREA'
103
+ >>> metres.inputs.current_sphere = 'fsaverage5_std_sphere.L.10k_fsavg_L.surf.gii'
104
+ >>> metres.inputs.new_sphere = 'fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii'
105
+ >>> metres.inputs.area_metrics = True
106
+ >>> metres.inputs.current_area = 'fsaverage5.L.midthickness_va_avg.10k_fsavg_L.shape.gii'
107
+ >>> metres.inputs.new_area = 'fs_LR.L.midthickness_va_avg.32k_fs_LR.shape.gii'
108
+ >>> metres.cmdline
109
+ 'wb_command -metric-resample sub-01_task-rest_bold_space-fsaverage5.L.func.gii \
110
+ fsaverage5_std_sphere.L.10k_fsavg_L.surf.gii \
111
+ fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii \
112
+ ADAP_BARY_AREA fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.out \
113
+ -area-metrics fsaverage5.L.midthickness_va_avg.10k_fsavg_L.shape.gii \
114
+ fs_LR.L.midthickness_va_avg.32k_fs_LR.shape.gii'
115
+ """
116
+ input_spec = MetricResampleInputSpec
117
+ output_spec = MetricResampleOutputSpec
118
+ _cmd = 'wb_command -metric-resample'
119
+
120
+ def _format_arg (self , opt , spec , val ):
121
+ if opt == "metric_out" :
122
+ # ensure generated filename is assigned to trait
123
+ self .inputs .trait_set (metric_out = val )
124
+ if opt in ['current_area' , 'new_area' ]:
125
+ if not self .inputs .area_surfs and not self .inputs .area_metrics :
126
+ raise ValueError ("{} was set but neither area_surfs or"
127
+ " area_metrics were set" .format (opt ))
128
+ if opt == "method" :
129
+ if (val == "ADAP_BARY_AREA" and
130
+ not self .inputs .area_surfs and
131
+ not self .inputs .area_metrics ):
132
+ raise ValueError ("Exactly one of area_surfs or area_metrics"
133
+ " must be specified" )
134
+ if opt == "valid_roi_out" and val :
135
+ # generate a filename and add it to argstr
136
+ roi_out = self ._gen_filename (self .inputs .in_file , suffix = '_roi' )
137
+ iflogger .info ("Setting roi output file as" , roi_out )
138
+ spec .argstr += " " + roi_out
139
+ return super (MetricResample , self )._format_arg (opt , spec , val )
140
+
141
+ def _list_outputs (self ):
142
+ outputs = self ._outputs ().get ()
143
+ outputs ['out_file' ] = os .path .abspath (self .inputs .metric_out )
144
+ if self .inputs .valid_roi_out :
145
+ roi_file = self ._gen_filename (self .inputs .in_file , suffix = '_roi' )
146
+ outputs ['roi_file' ] = os .path .abspath (roi )
147
+ return outputs
0 commit comments