def _convert_output(output): """Converts an output to a CWL output.""" if output.mapped_to: return ( cwlgen.CommandOutputParameter( "output_{}".format(output.mapped_to.stream_type), param_type=output.mapped_to.stream_type, streamable=False, ), None, ) entity = output.produces type_ = "Directory" if isinstance(entity, Collection) else "File" sanitized_id = output.sanitized_id.replace("/", "_") if output.position: # output is specified as a parameter, create an input as well separate = None prefix = None if output.prefix: prefix = output.prefix separate = False if prefix.endswith(" "): prefix = prefix[:-1] separate = True arg = cwlgen.CommandInputParameter( "{}_arg".format(sanitized_id), param_type="string", input_binding=cwlgen.CommandLineBinding( position=output.position, prefix=prefix, separate=separate), default=entity.path, ) outp = cwlgen.CommandOutputParameter( sanitized_id, param_type=type_, output_binding=cwlgen.CommandOutputBinding( glob="$(inputs.{})".format(arg.id)), ) return outp, arg return ( cwlgen.CommandOutputParameter( sanitized_id, param_type=type_, output_binding=cwlgen.CommandOutputBinding(glob=entity.path)), None, )
def createWorkflowStep(workflow, position, id, type, language="KNIME", extension=None): file_binding = cwlgen.CommandLineBinding() # Individual step input workflow_step = cwlgen.WorkflowStep(str(position), id + ".cwl") workflow_step.inputs.append( cwlgen.WorkflowStepInput("inputModule", "inputModule" + str(position))) if (not "external" in type): if (position == 1): workflow_step.inputs.append( cwlgen.WorkflowStepInput("potentialCases", "potentialCases")) else: workflow_step.inputs.append( cwlgen.WorkflowStepInput("potentialCases", source=str(position - 1) + "/output")) # Individual step output workflow_step.out.append(cwlgen.WorkflowStepOutput("output")) workflow.steps = workflow.steps + [workflow_step] # Overall workflow input if (position == 1 and (not "external" in type)): workflow_input = cwlgen.InputParameter( "potentialCases", param_type='File', input_binding=file_binding, doc="Input of potential cases for processing") workflow.inputs.append(workflow_input) workflow_input = cwlgen.InputParameter( "inputModule" + str(position), param_type='File', input_binding=file_binding, doc=language[0].upper() + language[1:] + " implementation unit") workflow.inputs.append(workflow_input) # Overall workflow output if (extension): workflow_output = cwlgen.WorkflowOutputParameter( param_id='cases', param_type="File", output_source=str(position) + "/output", output_binding=cwlgen.CommandOutputBinding(glob="*." + extension)) workflow.outputs.append(workflow_output) return workflow
def _convert_output(output): """Converts an output to a CWL output.""" if output.mapped_to: return cwlgen.CommandOutputParameter( 'output_{}'.format(output.mapped_to.stream_type), param_type=output.mapped_to.stream_type, streamable=False), None entity = output.produces type_ = 'Directory' if isinstance(entity, Collection) else 'File' if output.position: # output is specified as a parameter, create an input as well separate = None prefix = None if output.prefix: prefix = output.prefix separate = False if prefix.endswith(' '): prefix = prefix[:-1] separate = True arg = cwlgen.CommandInputParameter( '{}_arg'.format(output.sanitized_id), param_type='string', input_binding=cwlgen.CommandLineBinding( position=output.position, prefix=prefix, separate=separate), default=entity.path) outp = cwlgen.CommandOutputParameter( output.sanitized_id, param_type=type_, output_binding=cwlgen.CommandOutputBinding( glob='$(inputs.{})'.format(arg.id))) return outp, arg return cwlgen.CommandOutputParameter( output.sanitized_id, param_type=type_, output_binding=cwlgen.CommandOutputBinding(glob=entity.path)), None
def load_outbinding(self, output_obj, outbinding_el): """ Load the content of outputBinding into the output object. :param output_obj: output object :type output_obj: :class:`cwlgen.CommandOutputParameter` :param outbinding_el: Content of outputBinding element :type outbinding_el: DICT """ outbinding_obj = cwlgen.CommandOutputBinding() for key, value in outbinding_el.items(): try: getattr(self, '_load_{}'.format(key))(outbinding_obj, value) except AttributeError: _LOGGER.warning(key + " content for outputBinding is not processed (yet).") output_obj.outputBinding = outbinding_obj
def translate_tool_output(output, **debugkwargs): return cwlgen.CommandOutputParameter( param_id=output.tag, label=output.tag, secondary_files=output.output_type.secondary_files(), # param_format=None, # streamable=None, doc=output.doc, output_binding=cwlgen.CommandOutputBinding( glob=translate_to_cwl_glob(output.glob, outputtag=output.tag, **debugkwargs), # load_contents=False, # output_eval=None ), param_type=output.output_type.cwl_type(), )
def generate_cwl(cls): """ Produces a CWL App object which can then be exported to yaml """ import cwlgen module = cls.get_module() # Basic definition of the tool cwl_tool = cwlgen.CommandLineTool(tool_id=cls.name, label=cls.name, base_command=f'python3 -m {module}') #TODO: Add documentation in ceci elements cwl_tool.doc = "Pipeline element from ceci" # Add the inputs of the tool for i,inp in enumerate(cls.input_tags()): input_binding = cwlgen.CommandLineBinding(position=(i+1)) input_param = cwlgen.CommandInputParameter(inp, param_type='File', input_binding=input_binding, doc='Some documentation about the input') cwl_tool.inputs.append(input_param) # Add the definition of the outputs for i,out in enumerate(cls.output_tags()): output_binding = cwlgen.CommandOutputBinding(glob=out) output = cwlgen.CommandOutputParameter(out, param_type='File', output_binding=output_binding, param_format='http://edamontology.org/format_2330', doc='Some results produced by the pipeline element') cwl_tool.outputs.append(output) # Potentially add more metadata metadata = {'name': cls.name, 'about': 'I let you guess', 'publication': [{'id': 'one_doi'}, {'id': 'another_doi'}], 'license': ['MIT']} cwl_tool.metadata = cwlgen.Metadata(**metadata) return cwl_tool
def createStep(cwl_tool, cwl_tool_docker, implementation_file_binding, cases_file_binding, type, doc, input_doc, extension, output_doc, language="knime"): cwl_tool.namespaces.s = "http://phenomics.kcl.ac.uk/phenoflow/" metadata = {'type': type} cwl_tool.metadata = cwlgen.Metadata(**metadata) cwl_tool.doc = doc # Assume run in Docker cwl_tool.requirements.append(cwl_tool_docker) implementation_input_file = cwlgen.CommandInputParameter( "inputModule", param_type='File', input_binding=implementation_file_binding, doc=language[0].upper() + language[1:] + " implementation unit") cwl_tool.inputs.append(implementation_input_file) if ("external" not in type): data_input_file = cwlgen.CommandInputParameter( "potentialCases", param_type='File', input_binding=cases_file_binding, doc=input_doc) cwl_tool.inputs.append(data_input_file) workflow_output_binding = cwlgen.CommandOutputBinding(glob="*." + extension) output = cwlgen.CommandOutputParameter( 'output', doc=output_doc, param_type="File", output_binding=workflow_output_binding) cwl_tool.outputs.append(output) return cwl_tool
def add_output_file(self, output): """ Add an output to the CWL tool. :param output: Output object. :type output: :class:`tooldog.biotool_model.Output` """ LOGGER.info("Adding output to CwlToolGen object...") # Build parameter self.output_ct += 1 # Give unique name to the output name = 'OUTPUT' + str(self.output_ct) # Get all different format for this output list_formats = [] for format_obj in output.formats: list_formats.append(format_obj.uri) formats = ', '.join(list_formats) # Create the parameter param_binding = cwlgen.CommandOutputBinding(glob=name + '.ext') param = cwlgen.CommandOutputParameter(name, param_type='File', label=output.data_type.term, param_format=formats, output_binding=param_binding) self.tool.outputs.append(param)
def generate_cwl(cls): """ Produces a CWL App object which can then be exported to yaml """ import cwlgen module = cls.get_module() module = module.split('.')[0] # Basic definition of the tool cwl_tool = cwlgen.CommandLineTool(tool_id=cls.name, label=cls.name, base_command='python3', cwl_version='v1.0', doc=cls.__doc__) # Adds the first input binding with the name of the module and pipeline stage input_arg = cwlgen.CommandLineBinding(position=-1, value_from=f'-m{module}') cwl_tool.arguments.append(input_arg) input_arg = cwlgen.CommandLineBinding(position=0, value_from=f'{cls.name}') cwl_tool.arguments.append(input_arg) type_dict = { int: 'int', float: 'float', str: 'string', bool: 'boolean' } # Adds the parameters of the tool for opt in cls.config_options: def_val = cls.config_options[opt] # Handles special case of lists: if type(def_val) is list: v = def_val[0] param_type = { 'type': 'array', 'items': type_dict[v] if type(v) == type else type_dict[type(v)] } default = def_val if type(v) != type else None input_binding = cwlgen.CommandLineBinding( prefix='--{}='.format(opt), item_separator=',', separate=False) else: param_type = type_dict[def_val] if type( def_val) == type else type_dict[type(def_val)] default = def_val if type(def_val) != type else None if param_type is 'boolean': input_binding = cwlgen.CommandLineBinding( prefix='--{}'.format(opt)) else: input_binding = cwlgen.CommandLineBinding( prefix='--{}='.format(opt), separate=False) input_param = cwlgen.CommandInputParameter( opt, label=opt, param_type=param_type, input_binding=input_binding, default=default, doc='Some documentation about this parameter') # We are bypassing the cwlgen builtin type check for the special case # of arrays until that gets added to the standard if type(def_val) is list: input_param.type = param_type cwl_tool.inputs.append(input_param) # Add the inputs of the tool for i, inp in enumerate(cls.input_tags()): input_binding = cwlgen.CommandLineBinding( prefix='--{}'.format(inp)) input_param = cwlgen.CommandInputParameter( inp, label=inp, param_type='File', param_format=cls.inputs[i][1].__name__, input_binding=input_binding, doc='Some documentation about the input') cwl_tool.inputs.append(input_param) # Adds the overall configuration file input_binding = cwlgen.CommandLineBinding(prefix='--config') input_param = cwlgen.CommandInputParameter('config', label='config', param_type='File', param_format='YamlFile', input_binding=input_binding, doc='Configuration file') cwl_tool.inputs.append(input_param) # Add the definition of the outputs for i, out in enumerate(cls.output_tags()): output_name = f'{out}.{cls.outputs[i][1].suffix}' output_binding = cwlgen.CommandOutputBinding(glob=output_name) output = cwlgen.CommandOutputParameter( out, label=out, param_type='File', output_binding=output_binding, param_format=cls.outputs[i][1].__name__, doc='Some results produced by the pipeline element') cwl_tool.outputs.append(output) # Potentially add more metadata # This requires a schema however... # metadata = {'name': cls.name, # 'about': 'Some additional info', # 'publication': [{'id': 'one_doi'}, {'id': 'another_doi'}], # 'license': ['MIT']} # cwl_tool.metadata = cwlgen.Metadata(**metadata) return cwl_tool
def setUp(self): self.out_binding = cwlgen.CommandOutputBinding(glob='file.txt', load_contents=True,\ output_eval='eval')
type_script = cwlgen.CommandInputParameter( 'script_type', param_type='string', input_binding=script_type_binding, doc='choose pw or wstat') west_tool.inputs.append(type_script) core_binding = cwlgen.CommandLineBinding(position=5) cores = cwlgen.CommandInputParameter('no_of_cores', param_type='int', input_binding=core_binding, doc='choose 2, 3, 4') west_tool.inputs.append(cores) # Add 1 output with type to fetch output_bind = cwlgen.CommandOutputBinding(glob="*.out") output = cwlgen.CommandOutputParameter( 'west_output_file', param_type='File', output_binding=output_bind, doc='Output File generated with west pw.x or wstat.x code') west_tool.outputs.append(output) # Add documentation west_tool.doc = "Runs west code for different input paramaters" # Add Metadata metadata = { 'name': 'West', 'about':
# Add 2 inputs input_1_binding = cwlgen.CommandLineBinding(position=1) input_1 = cwlgen.CommandInputParameter('config_file', param_type='File',\ input_binding=input_1_binding,\ doc='config file',\ param_format='http://edamontology.org/format_2330') cwl_tool.inputs.append(input_1) input_2_binding = cwlgen.CommandLineBinding(prefix='-t') input_2 = cwlgen.CommandInputParameter('threads', param_type='int',\ input_binding=input_2_binding,\ doc='number of threads') cwl_tool.inputs.append(input_2) # Add 1 output output_1_binding = cwlgen.CommandOutputBinding(glob='counts.txt') output_1 = cwlgen.CommandOutputParameter('result_file', param_type='File',\ output_binding=output_1_binding,\ param_format='http://edamontology.org/format_2330',\ doc='magic results') cwl_tool.outputs.append(output_1) # Add Metadata metadata = { 'name': 'my tool', 'about': 'I let you guess', 'publication': [{ 'id': 'one_doi' }, { 'id': 'another_doi' }],
def generate_cwl(cls, log_dir=None): """ Produces a CWL App object which can then be exported to yaml """ import cwlgen module = cls.get_module() module = module.split(".")[0] # Basic definition of the tool cwl_tool = cwlgen.CommandLineTool( tool_id=cls.name, label=cls.name, base_command="python3", cwl_version="v1.0", doc=cls.__doc__, ) if log_dir is not None: cwl_tool.stdout = f"{cls.name}.out" cwl_tool.stderr = f"{cls.name}.err" # Adds the first input binding with the name of the module and pipeline stage input_arg = cwlgen.CommandLineBinding(position=-1, value_from=f"-m{module}") cwl_tool.arguments.append(input_arg) input_arg = cwlgen.CommandLineBinding(position=0, value_from=f"{cls.name}") cwl_tool.arguments.append(input_arg) type_dict = {int: "int", float: "float", str: "string", bool: "boolean"} # Adds the parameters of the tool for opt, def_val in cls.config_options.items(): # Handles special case of lists: if isinstance(def_val, list): v = def_val[0] param_type = { "type": "array", "items": type_dict[v] if isinstance(v, type) else type_dict[type(v)], } default = def_val if not isinstance(v, type) else None input_binding = cwlgen.CommandLineBinding( prefix=f"--{opt}=", item_separator=",", separate=False ) else: param_type = ( type_dict[def_val] if isinstance(def_val, type) else type_dict[type(def_val)] ) default = def_val if not isinstance(def_val, type) else None if param_type == "boolean": input_binding = cwlgen.CommandLineBinding(prefix=f"--{opt}") else: # pragma: no cover input_binding = cwlgen.CommandLineBinding( prefix=f"--{opt}=", separate=False ) input_param = cwlgen.CommandInputParameter( opt, label=opt, param_type=param_type, input_binding=input_binding, default=default, doc="Some documentation about this parameter", ) # We are bypassing the cwlgen builtin type check for the special case # of arrays until that gets added to the standard if isinstance(def_val, list): input_param.type = param_type cwl_tool.inputs.append(input_param) # Add the inputs of the tool for i, inp in enumerate(cls.input_tags()): input_binding = cwlgen.CommandLineBinding(prefix=f"--{inp}") input_param = cwlgen.CommandInputParameter( inp, label=inp, param_type="File", param_format=cls.inputs[i][1].format, # pylint: disable=no-member input_binding=input_binding, doc="Some documentation about the input", ) cwl_tool.inputs.append(input_param) # Adds the overall configuration file input_binding = cwlgen.CommandLineBinding(prefix="--config") input_param = cwlgen.CommandInputParameter( "config", label="config", param_type="File", param_format="http://edamontology.org/format_3750", input_binding=input_binding, doc="Configuration file", ) cwl_tool.inputs.append(input_param) # Add the definition of the outputs for i, out in enumerate(cls.output_tags()): output_name = cls.outputs[i][1].make_name(out) # pylint: disable=no-member output_binding = cwlgen.CommandOutputBinding(glob=output_name) output = cwlgen.CommandOutputParameter( out, label=out, param_type="File", output_binding=output_binding, param_format=cls.outputs[i][1].format, # pylint: disable=no-member doc="Some results produced by the pipeline element", ) cwl_tool.outputs.append(output) if log_dir is not None: output = cwlgen.CommandOutputParameter( f"{cls.name}@stdout", label="stdout", param_type="stdout", doc="Pipeline elements standard output", ) cwl_tool.outputs.append(output) error = cwlgen.CommandOutputParameter( f"{cls.name}@stderr", label="stderr", param_type="stderr", doc="Pipeline elements standard output", ) cwl_tool.outputs.append(error) # Potentially add more metadata # This requires a schema however... # metadata = {'name': cls.name, # 'about': 'Some additional info', # 'publication': [{'id': 'one_doi'}, {'id': 'another_doi'}], # 'license': ['MIT']} # cwl_tool.metadata = cwlgen.Metadata(**metadata) return cwl_tool