4. Perguntas Frequentes (FAQ)#
4.1. How do I create non «File
» types using evalFrom
?#
cwlVersion: v1.0 # or v1.1
class: CommandLineTool
requirements:
InlineJavascriptRequirement: {}
baseCommand: [ echo, "42" ]
inputs: []
stdout: my_number.txt
outputs:
my_number:
type: int
outputBinding:
glob: my_number.txt
loadContents: True
outputEval: $(parselnt(self[0].contents))
my_number_as_string:
type: string
outputBinding:
glob: my_number.txt
loadContents: True
outputEval: $(self[0].contents)
4.2. How do I rename an input file?#
Este exemplo demonstra como mudar o nome de um arquivo de entrada como parte da descrição da ferramenta. Isso pode ser útil quando você tem arquivos produzidos em outro passo de um workflow, mas prefere não utilizar os nomes dados por padrão quando estes arquivos foram criados.
requirements:
InitialWorkDirRequirement:
listing:
- entry: $(inputs.src1)
entryName: newName
- entry: $(inputs.src2)
entryName: $(inputs.src1.basename)_custom_extension
4.3. How do I rename an output file?#
Este exemplo demonstra como escolher o nome para um arquivo de saída diferente do nome padrão criado por uma ferramenta:
cwlVersion: v1.0
class: CommandLineTool
requirements:
InlineJavascriptRequirement: {}
baseCommand: [ touch, otu_table.txt ]
inputs:
otu_table_name: string
outputs:
otu_table:
type: File
outputBinding:
glob: otu_table.txt
outputEval: ${self[0].basename=inputs.otu_table_name; return self;}
By modifying the basename
field in the outputEval
field, CWL workflow engines will rename
the file using the new name for subsequent steps or as a workflow-level output.
4.4. How do I reference a local script?#
Há duas maneiras de fazer uma referência a um script local:
The first method involves adding the path to a folder containing your scripts to the PATH
environment variable. This
allows you to execute the shell script directly (without explicitly using the sh
or bash
commands).
Comece adicionando a shebang no topo do seu arquivo:
#!/bin/bash
Em seguida faça o seu script executável com o comando chmod +x scriptname.sh
E finalmente, modifique o seu PATH
para adicionar o diretório que contém o seu script. (É boa prática usar $HOME/bin
para scripts do utilizador local).
export PATH=$PATH:$HOME/bin
Agora você pode utilizar baseCommand: scriptname.sh
para rodar o script diretamente.
#!/bin/bash
cwlVersion: v1.0
class: CommandLineTool
baseCommand: scriptname.sh
Depois quando você quiser compartilhar o seu trabalho, é possível utilizar um container de software com ferramentas como Docker.
O segundo método utiliza um input type: File
diretamente no script:
class: CommandLineTool
inputs:
my_script:
type: File
inputBinding:
position: 0
# other inputs go here
baseCommand: sh
outputs: []
4.5. How can I set self
-based input bindings for optional inputs?#
No momento cwltool
não funciona quando inputs opcionais não estão presentes se o binding de input deles utilizar self
. O exemplo abaixo contém uma solução alternativa para este problema, até que haja uma solução mais elegante para este problema.
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
requirements: { InlineJavascriptRequirement: {} }
inputs:
cfg:
type: File?
inputBinding:
prefix: -cfg
valueFrom: |
${ if(self === null) { return null;} else { return self.basename; } }
baseCommand: echo
outputs: []
4.6. How can I model a «one-or-the-other» parameter?#
O exemplo abaixo demonstra como especificar diferentes strings que serão adicionadas à linha de comando, dependendo do valor de um parâmetro Boolean.
cwlVersion: v1.0
class: CommandLineTool
requirements:
InlineJavascriptRequirement: {}
inputs:
fancy_bool:
type: boolean
default: false # or true
inputBinding:
valueFrom: ${if (self) { return "foo";} else { return "bar";}}
baseCommand: echo
outputs: []
4.7. How do I connect a solo value to an input that expects an array of that type?#
Add a MultipleInputFeatureRequirement
along with
linkMerge: merge_nested
:
merge_nested
The input must be an array consisting of exactly one entry for each input link. If «merge_nested» is specified with a single link, the value from the link must be wrapped in a single-item list.
Which means «create a list with exactly these sources as elements».
Ou em outras palavras: se o parâmetro destino for do tipo File[]
(uma lista de File
s) e a fonte é um único File
, adicione então MultipleInputFeatureRequirement
ao requirements
no nível do Workflow e adicione linkMerge: merge_nested
sob a entrada apropriada in
ao step que receberá o parâmetro (target).
cwlVersion: v1.0
class: Workflow
requirements:
MultipleInputFeatureRequirement: {}
inputs:
readme: File
steps:
first:
run: tests/checker_wf/cat.cwl
in:
cat_in: # type is File[]
source: [ readme ] # but the source is of type File
linkMerge: merge_nested
out: [txt]
outputs:
result:
type: File
outputSource: first/txt
4.8. How do make an input optional? 💯#
Para fazer um parâmetro de entrada opcional, adicione um ponto de interrogação à declaração do tipo.
inputs:
InputRead1:
type: File
inputBinding:
position: 100
#Optional Inputs
isCasava:
type: boolean?
inputBinding:
position: 1
prefix: "--casava"
4.9. How do I specify an input that must come from a list of predefined values (i.e. How do I use enum inputs) ?#
O tipo enum por ser utilizado em CWL para flags de linha de comando que requerem um tipo de input específico como argumento. Especificar null aqui é tido como forma estendida. O resultado é o mesmo que o uso do ponto de interrogação nos outros inputs.
Format:
type:
- "null"
- type: enum
symbols:
- bam
- sam
- bam_mapped
- sam_mapped
- fastq
inputBinding:
position: 2
prefix: "--format"
4.10. How do I describe dependent or exclusive input parameters(e.g. How do I use record inputs)?#
For commandline flags that are either mutually exclusive or dependent a special record type can be defined. You can also specify null here to create optional inputs.
#Using record inputs to create mutually exclusive inputs
Strand:
type:
- "null"
- type: record
name: forward
fields:
forward:
type: boolean
inputBinding:
prefix: "--fr-stranded"
- type: record
name: reverse
fields:
reverse:
type: boolean
inputBinding:
prefix: "--rf-stranded"
PseudoBam:
type: boolean?
inputBinding:
prefix: "--pseudobam"
#Using record inputs to create dependent inputs
GenomeBam:
type:
- "null"
- type: record
name: genome_bam
fields:
genomebam:
type: boolean
inputBinding:
prefix: "--genomebam"
gtf:
type: File
inputBinding:
prefix: "--gtf"
chromosomes:
type: File
inputBinding:
prefix: "--chromosomes"
4.11. How do I set mutually exclusive parameters?#
To properly set fields in a record input type, you need to pass a dictionary to the input to properly set the parameters. This is done by using inline JavaScript and returning the dictionary with the key of the field you want to set. The source field is set to indicate the input from the workflow to be used as the value.
steps:
build_hisat2_index:
run: ../Tools/Hisat2-Index.cwl
in:
InputFiles:
source: FastaFiles
valueFrom : |
${return {"fasta": self};}
IndexName: IndexName
out: [indexes]
4.12. How can I set Booleans?#
Estes são definidos através do campo padrão
input:
default: true
4.13. What should I do when concatenating strings in inputs?#
O campo valueFrom deve ser utilizado ao invés do valor padrão.
input:
valueFrom: |
My String: $(input.stringvalue)
4.14. I get cwltool
errors due to filenames with space characters inside. What should I do?#
O cwltool
não permite alguns caracteres em nomes de arquivos por padrão.
Por exemplo, o nome de arquivo um espaco vai aqui.txt
inclui 3 espaços…
ERROR Workflow error, try again with --debug for more information:
Invalid filename: 'a space is here.txt' contains illegal characters
Se você não tem opção e precisa utilizar estes caracteres apesar do risco, você deve então passar --relax-path-verificks
ao chamar o cwltool
.
4.15. What should I do when I get CWL Parameter Reference error due to hyphen in an input identifier?#
Se cwltool --validate
valida com sucesso
$ cwltool --validate cwl/qiime.cwl
INFO /usr/local/bin/cwltool 1.0.20190831161204
INFO Resolved 'cwl/qiime.cwl' to 'file:///workspace/cwl/qiime.cwl'
cwl/qiime.cwl is valid CWL.
Mas ao executar o workflow um erro como o seguinte aparece:
$ cwltool cwl/qiime.cwl --sample-input metadata.tsv
INFO /usr/local/bin/cwltool 1.0.20190831161204
INFO Resolved 'cwl/qiime.cwl' to 'file:///workspace/cwl/qiime.cwl'
ERROR Workflow error, try again with --debug for more information:
cwl/qiime.cwl:14:5: Expression evaluation error:
Syntax error in parameter reference '(inputs.sample-input)'. This could be due
to using Javascript code without specifying InlineJavascriptRequirement.
Este é o arquivo
cwlVersion: v1.0
class: CommandLineTool
baseCommand: [qiime, metadata, tabulate]
arguments:
- prefix: --m-input-file
valueFrom: $(inputs.sample-input)
inputs:
sample-input: File
outputs: []
O problema é causado pelo -
(hífen).
valueFrom: $(inputs.sample-input)
# ^ this is problem
...
inputs:
sample-input: File
# ^ this is problem
To fix this error, change -
(hyphen) to _
(underscore):
valueFrom: $(inputs.sample_input)
# ^ changed here
...
inputs:
sample_input: File
# ^ changed here
Se não for possível mudar o identificador do input, você pode reescrever utilizando uma sintaxe alternativa para Referências de Parâmetros CWL:
valueFrom: $(inputs["sample-input"])
4.16. How do I use CWL and cwltool with Singularity?#
The CWL standards are built around (optional) Docker format containers. The reference runner and several other CWL implementations support running those Docker format containers using the Singularity engine. Directly specifying a Singularity format container is not part of the CWL standards.
4.17. How do I debug the JavaScript in my CWL tool?#
You can use the –js-console
option of cwltool
, or you can try
creating a JavaScript or TypeScript project for your code, and load it
using expressionLib
, e.g.:
https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/v1.0/template-tool.cwl#L6-L8