19
19
_LOGGER = logging .getLogger (__name__ )
20
20
21
21
SCATTER_METHODS = ["dotproduct" , "nested_crossproduct" , "flat_crossproduct" ]
22
+ LINK_MERGE_METHODS = ["merge_nested" , "merge_flattened" ]
22
23
23
24
24
25
# Function(s) ------------------------------
@@ -30,6 +31,15 @@ def parse_scatter_method(scatter_method):
30
31
return scatter_method
31
32
32
33
34
+ def parse_link_merge_method (link_merge ):
35
+ if link_merge not in LINK_MERGE_METHODS :
36
+ _LOGGER .warning ("The link merge method '{method}' is not a valid LinkMergeMethod, expected one of: {expected}. "
37
+ "This value will be null which CWL defaults to 'merge_nested'"
38
+ .format (method = link_merge , expected = " ," .join (LINK_MERGE_METHODS )))
39
+ return None
40
+ return link_merge
41
+
42
+
33
43
# Class(es) ------------------------------
34
44
35
45
class Workflow (object ):
@@ -216,44 +226,84 @@ def get_dict(self):
216
226
217
227
218
228
class Wor
8000
kflowStepInput (object ):
219
- def __init__ (self , id , src = None , default = None ):
229
+ def __init__ (self , input_id , source = None , link_merge = None , default = None , value_from = None ):
220
230
"""
221
- :param id: ID of the step input
222
- :type id: STRING
223
- :param src:
224
- :type src:
225
- :param default:
226
- :type default:
231
+ The input of a workflow step connects an upstream parameter (from the workflow inputs, or the outputs of
232
+ other workflows steps) with the input parameters of the underlying step.
233
+ Documentation: https://www.commonwl.org/v1.0/Workflow.html#WorkflowStepInput
234
+ :param input_id: A unique identifier for this workflow input parameter.
235
+ :type input_id: STRING
236
+ :param source: Specifies one or more workflow parameters that will provide input to the underlying step parameter.
237
+ :type source: STRING | list[STRING]
238
+ :param link_merge: The method to use to merge multiple inbound links into a single array.
239
+ If not specified, the default method is "merge_nested".
240
+ :type link_merge: LinkMergeMethod
241
+ :param default: The default value for this parameter to use if either there is no source field,
242
+ or the value produced by the source is null
243
+ :type default: Any | DictRepresentible
244
+ :param value_from: If valueFrom is a constant string value, use this as the value for this input parameter.
245
+ If valueFrom is a parameter reference or expression,
246
+ it must be evaluated to yield the actual value to be assiged to the input field.
247
+ :type value_from: STRING
227
248
"""
228
- self .id = id
229
- self .src = src
249
+
250
+ self .id = input_id
251
+ self .source = source
252
+ self .linkMerge = parse_link_merge_method (link_merge )
230
253
self .default = default
254
+ self .valueFrom = self .valueFrom
255
+
231
256
232
257
def get_dict (self ):
233
258
"""
234
259
Transform the object to a [DICT] to write CWL.
235
-
236
- :return: dictionnary of the object
260
+ :return: dictionary of the object
237
261
:rtype: DICT
238
262
"""
239
- dict_param = {} # {k: v for k, v in vars(self).items() if v is not None and v is not False}
240
- if self .src :
241
- dict_param ["src" ] = self .src
263
+ dict_param = {
264
+ 'id' : self .id ,
265
+ 'source' : self .source
266
+ }
267
+
268
+ if self .linkMerge :
269
+ dict_param ['linkMerge' ] = self .linkMerge
270
+
242
271
if self .default :
243
- dict_param ["default" ] = self .default
272
+ dict_param ['default' ] = self .default
273
+
274
+ if self .valueFrom :
275
+ dict_param ['valueFrom' ] = self .valueFrom
276
+
244
277
return dict_param
245
278
246
279
247
280
class WorkflowStepOutput (object ):
248
- def __init__ (self , id ):
281
+ """
282
+ Associate an output parameter of the underlying process with a workflow parameter.
283
+ The workflow parameter (given in the id field) be may be used as a source to connect with
284
+ input parameters of other workflow steps, or with an output parameter of the process.
285
+
286
+ Documentation: https://www.commonwl.org/v1.0/Workflow.html#WorkflowStepOutput
287
+ """
288
+ def __init__ (self , output_id ):
249
289
"""
250
- :param id:
251
- :type id:
290
+ :param output_id: A unique identifier for this workflow output parameter. This is the identifier to use in
291
+ the source field of WorkflowStepInput to connect the output value to downstream parameters.
292
+ :type output_id: STRING
252
293
"""
253
- self .id = id
294
+ self .id = output_id
295
+
296
+ def get_dict (self ):
297
+ return self .id
254
298
255
299
256
300
class WorkflowOutputParameter (Parameter ):
301
+ """
302
+ Describe an output parameter of a workflow. The parameter must be connected to one or more parameters
303
+ defined in the workflow that will provide the value of the output parameter.
304
+
305
+ Documentation: https://www.commonwl.org/v1.0/Workflow.html#WorkflowOutputParameter
306
+ """
257
307
def __init__ (self , param_id , outputSource = None , label = None , secondary_files = None , param_format = None ,
258
308
streamable = False , doc = None , param_type = None , output_binding = None , linkMerge = None ):
259
309
"""
@@ -301,10 +351,10 @@ def get_dict(self):
301
351
302
352
return output_dict
303
353
354
+
304
355
############################
305
356
# Workflow construction classes
306
357
307
-
308
358
class File :
309
359
"""
310
360
An abstract file reference used for generating workflows
@@ -333,39 +383,39 @@ def store(self):
333
383
return
334
384
335
385
336
- class StepRun :
337
- """
338
- Result of adding a step into a workflow
339
- """
340
- def __init__ (self , workflow , id , tool , params ):
341
- self .tool = tool
342
- self .workflow = workflow
343
- self .id = id
344
-
345
- step = WorkflowStep (id = id , run = tool ._path )
346
- workflow .steps .append (step )
347
-
348
- for i , j in params .items ():
349
- if isinstance (j , six .string_types ):
350
- step .inputs .append (WorkflowStepInput (i , default = j ))
351
- elif isinstance (j , Variable ):
352
- step .inputs .append (WorkflowStepInput (i , src = j .path ()))
353
- elif isinstance (j , InputParameter ):
354
- self .workflow .inputs .append (j ),
355
- step .inputs .append (WorkflowStepInput (j .id , src = j .id ))
356
- elif isinstance (j , File ):
357
- # This is just used as a stub, the 'path' inside the file doesn't do anything
358
- self .workflow .inputs .append (InputParameter (i , param_type = "File" ))
359
- step .inputs .append (WorkflowStepInput (i , src = i ))
360
- for o in tool .outputs :
361
- step .outputs .append (o .id )
362
-
363
- def store_all (self ):
364
- for i in self .tool .outputs :
365
- Variable (self .workflow , self .id , i .id ).store ()
366
-
367
- def __getitem__ (self , key ):
368
- for i in self .tool .outputs :
369
- if i .id == key :
370
- return Variable (self .workflow , self .id , key )
371
- raise KeyError
386
+ # class StepRun:
387
+ # """
388
+ # Result of adding a step into a workflow
389
+ # """
390
+ # def __init__(self, workflow, id, tool, params):
391
+ # self.tool = tool
392
+ # self.workflow = workflow
393
+ # self.id = id
394
+ #
395
+ # step = WorkflowStep(id=id, run=tool._path)
396
+ # workflow.steps.append(step)
397
+ #
398
+ # for i, j in params.items():
399
+ # if isinstance(j, six.string_types):
400
+ # step.inputs.append(WorkflowStepInput(i, default=j))
401
+ # elif isinstance(j, Variable):
402
+ # step.inputs.append(WorkflowStepInput(i, src=j.path()))
403
+ # elif isinstance(j, InputParameter):
404
+ # self.workflow.inputs.append(j),
405
+ # step.inputs.append(WorkflowStepInput(j.id, src=j.id))
406
+ # elif isinstance(j, File):
407
+ # # This is just used as a stub, the 'path' inside the file doesn't do anything
408
+ # self.workflow.inputs.append(InputParameter(i, param_type="File"))
409
+ # step.inputs.append(WorkflowStepInput(i, src=i))
410
+ # for o in tool.outputs:
411
+ # step.outputs.append(o.id)
412
+ #
413
+ # def store_all(self):
414
+ # for i in self.tool.outputs:
415
+ # Variable(self.workflow, self.id, i.id).store()
416
+ #
417
+ # def __getitem__(self, key):
418
+ # for i in self.tool.outputs:
419
+ # if i.id == key:
420
+ # return Variable(self.workflow, self.id, key)
421
+ # raise KeyError
0 commit comments