This is a test version of Biostars. For the public version, visit https://www.biostars.org.
cwl: how to add optional input as one element or as array of elements ?

I often need support optional input as File or as array of File entries. For example, I want to create command line option like the following: --opt A --opt B --opt C

I can define the following in cwl:

inputs:
   opt:
    type:
      - "null"
      - type: array
        items: File
        inputBinding:
          prefix: --opt

However this won't support single element input if not as an array. I wish I could do the following:

inputs:
   opt:
    type:
      - "null"
      - type: array
        items: File
        inputBinding:
          prefix: --opt
      - type: File
        inputBinding:
          prefix: --opt

It will complain about the - type: File as

* the `type` field is not valid because
  the value 'File' is not a valid Record_symbol, expected
  'record'

Any help would be appreciated.

cwl

3 answers

Hello liuxf09,

Try the following, though it is a bit of a hack:

inputs:
  opt:
    type:
      - "null"
      - type: array
        items: File
      - File
    inputBinding:
        prefix: --opt
        itemSeparator: " --opt "

Optionally you can just provide the single item as an one element array:

your input object:

opt:
  - class: File
    path: path/to/my/file

inputs stanza:

inputs:
  opt:
    type:
      - "null"
      - type: array
        items: File
        inputBinding:
          prefix: --opt

I tried the hack to use itemSeparator. But the command line created has quote for items connected by itemSeparator, which causes error in option parsing in the binary. It is common in my application to mix usage of single input or multiple inputs like --opt input1 --opt input 2. Is it a good idea to add another option for inputBinding to distinguish between '--opt input1 input2' and "--opt input1 --opt inptu2"? I feel that both are common enough.

Then the second option I gave should work for you as it prefixed "--opt" prior to each item.

inputs:
  opt:
    type:
      - "null"
      - type: array
        items: File
        inputBinding:
          prefix: --opt

give "--opt file2 --opt file2"

while

inputs:
  opt:
    type:
      - "null"
      - type: array
        items: File
    inputBinding:
        prefix: --opt

gives "--opt file1 file2"

I used the solution here: How to convert File to array of File? Type mismatch between source and sink, File to array

There is nargs if your number of arguments (files here) is variable, i.e., you may at time have only two files as input or sometime three or any number. You can parse your input.
You can consider your argparse if your number input files remains same.

Hi, Bioinformatics_NewComer: I think I don't understand what you meant. Can you give some code example? Thanks

Log in to answer this question.