@@ -78,12 +78,20 @@ def generate_boutiques_descriptor(
78
78
input = get_boutiques_input (inputs , interface , name , spec ,
79
79
ignored_template_inputs , verbose ,
80
80
ignore_template_numbers )
81
+ # Handle compound inputs (inputs that can be of multiple types and are mutually exclusive)
81
82
if isinstance (input , list ):
83
+ mutex_group_members = []
82
84
for i in input :
83
85
tool_desc ['inputs' ].append (i )
84
86
tool_desc ['command-line' ] += i ['value-key' ] + " "
87
+ mutex_group_members .append (i ['id' ])
85
88
if verbose :
86
89
print ("-> Adding input " + i ['name' ])
90
+ # Put inputs into a mutually exclusive group
91
+ tool_desc ['groups' ] = [{'id' : input [0 ]['id' ] + "_group" ,
92
+ 'name' : input [0 ]['name' ],
93
+ 'members' : mutex_group_members ,
94
+ 'mutually-exclusive' : True }]
87
95
else :
88
96
tool_desc ['inputs' ].append (input )
89
97
tool_desc ['command-line' ] += input ['value-key' ] + " "
@@ -123,7 +131,8 @@ def generate_boutiques_descriptor(
123
131
124
132
def get_boutiques_input (inputs , interface , input_name , spec ,
125
133
ignored_template_inputs , verbose ,
126
- ignore_template_numbers , handler = None , input_number = None ):
134
+ ignore_template_numbers , handler = None ,
135
+ input_number = None ):
127
136
"""
128
137
Returns a dictionary containing the Boutiques input corresponding to a Nipype intput.
129
138
@@ -134,6 +143,8 @@ def get_boutiques_input(inputs, interface, input_name, spec,
134
143
* spec: Nipype input spec.
135
144
* ignored_template_inputs: input names for which no temporary value must be generated.
136
145
* ignore_template_numbers: True if numbers must be ignored in output path creations.
146
+ * handler: used when handling compound inputs, which don't have their own input spec
147
+ * input_number: used when handling compound inputs to assign each a unique ID
137
148
138
149
Assumes that:
139
150
* Input names are unique.
@@ -142,7 +153,7 @@ def get_boutiques_input(inputs, interface, input_name, spec,
142
153
143
154
input = {}
144
155
145
- if input_number is not None :
156
+ if input_number is not None and input_number != 0 : # No need to append a number to the first of a list of compound inputs
146
157
input ['id' ] = input_name + "_" + str (input_number + 1 )
147
158
else :
148
159
input ['id' ] = input_name
@@ -158,7 +169,6 @@ def get_boutiques_input(inputs, interface, input_name, spec,
158
169
handler_type = type (trait_handler ).__name__
159
170
160
171
# Deal with compound traits
161
- # TODO create a mutually exclusive group for members of compound traits
162
172
if handler_type == "TraitCompound" :
163
173
input_list = []
164
174
# Recursively create an input for each trait
@@ -341,34 +351,6 @@ def get_boutiques_output(outputs, name, spec, interface, tool_inputs, verbose=Fa
341
351
return output
342
352
343
353
344
- # TODO remove this
345
- def get_type_from_spec_info (spec_info ):
346
- '''
347
- Returns an input type from the spec info. There must be a better
348
- way to get an input type in Nipype than to parse the spec info.
349
- '''
350
- if ("an existing file name" in spec_info ) or (
351
- "input volumes" in spec_info ):
352
- return "File"
353
- elif ("an integer" in spec_info or "a float" in spec_info ):
354
- return "Number"
355
- elif "a boolean" in spec_info :
356
- return "Boolean"
357
- return "String"
358
-
359
-
360
- # TODO remove this
361
- def is_list (spec_info ):
362
- '''
363
- Returns True if the spec info looks like it describes a list
364
- parameter. There must be a better way in Nipype to check if an input
365
- is a list.
366
- '''
367
- if "a list" in spec_info :
368
- return True
369
- return False
370
-
371
-
372
354
def get_unique_value (type , id ):
373
355
'''
374
356
Returns a unique value of type 'type', for input with id 'id',
0 commit comments