一、介绍
什么是Common Workflow Language?
CWL是一种描述命令行工具,它能能够将命令行衔接起来,连接成工作流。由于CWL是工作流的说明,而不是一种特定的软件、工具。由CWL描述的工作流能够在支持CWL的多种平台上使用。
CWL任务是独立的,必须明确输入和输出。根据任务之间的依赖关系来确定执行顺序。 用 CWL描述的工具和工作流可以利用 docker 等技术,并与不同vendors的CWL实现一起使用。 CWL 非常适合描述集群、云和高性能计算环境中的大规模工作流,在这些环境中,任务在多个节点上并行调度。
总结
- CWL描述命令行工具和工作流;
- CWL不是软件;
- CWL的描述,使得它在环境之间具有可移植性;
二、一个实例
最简单的”hello world”程序。 它接受一个输入参数,将消息写入终端或作业日志,并且生成非永久输出。 CWL 文件以json或yam或两者的混合形式编写。 在本指南中,使用 yaml。 如果不熟悉 yaml,参考。
注意:缩进都不能使用制表符创建。
1st-tool.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs:
message:
type: string
inputBinding:
position: 1
outputs: []
接下来,创建一个名为 echo-job. yml 的文件,用于描述运行的输入:
echo-job.yml
message: Hello world!
现在,用1st-tool.cwl中的工具包装器调用cwl-runner
。 在命令行中,输入echo-job.yml。 命令是cwl-runner 1st-tool.cwl echo-job.yml
。下面显示命令和输出。
$ cwl-runner 1st-tool.cwl echo-job.yml
[job 1st-tool.cwl] /tmp/tmpmM5S_1$ echo \
'Hello world!'
Hello world!
[job 1st-tool.cwl] completed success
{}
Final process status is success
命令 cwl-runner 1st-tool.cwl echo-job.yml
是一个一般形式的例子,会经常遇到。 通用形式是 cwl-runner [tool-or-workflow-description] [input-job-settings]
cwlVersion: v1.0
class: CommandLineTool
cwlVersion
:该字段表示文档使用的 cwl 版本。
class
:该字段表示这个文档描述了一个命令行工具。
baseCommand: echo
baseCommand
:提供了实际运行的程序名(‘ echo’)。 Echo 是 bash 和 c shell 中的内置程序。
inputs:
message:
type: string
inputBinding:
position: 1
inputs
输入部分描述了工具的输入。 这是一个映射的输入参数列表(有关格式的更多信息,请参阅 yaml guide ) ,每个参数包括一个标识符、一个数据类型和一个可选的inputbinding
。inputBinding
描述了这个输入参数应该如何出现在命令行上。 在这个例子中,position
字段表示它应该出现在命令行上的位置。
outputs: []
这个工具没有正式的输出,因此outputs
部分是一个空列表。.
总结
- cwl 文件以 yaml 和或 json的格式编写。
- 所调用的命令用
baseCommand
指定。 - 输入都在
inputs
部分中描述。 - 输入参数的值在单独的 yaml 文件中指定。
- 工具描述和输入文件作为参数提供给一个 cwl runner。
三、基本的输入参数
问题
- 如何将参数传递给命令?
- 如何为命令定义参数顺序?
每个工具的
inputs
都含有一个输入参数列表,控制如何运行工具. 每个参数的name都有一个id
,type
描述哪些类型的值对该参数有效。
- 可用的基本类型:string, int, long, float, double, null;
- 复杂类型:array, record;
- 特殊类型:File, Directory and Any.
下面的示例演示了一些不同类型的输入参数,它们以不同的方式出现在命令行上:
首先,创建一个名为 inp.cwl 的文件,包含以下内容:
inp.cwl boolean | string | int |
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs:
example_flag:
type: boolean
inputBinding:
position: 1
prefix: -f
example_string:
type: string
inputBinding:
position: 3
prefix: --example-string
example_int:
type: int
inputBinding:
position: 2
prefix: -i
separate: false
example_file:
type: File?
inputBinding:
prefix: --file=
separate: false
position: 4
outputs: []
创建一个名为 inp-job 的文件:
inp-job.yml boolean | string | int |
example_flag: true
example_string: hello
example_int: 42
example_file:
class: File
path: whale.txt
注意,“示例文件”作为File
类型,必须作为对象含有class: File
和path
字段
接下来,使用 touch创建 whale.txt,在命令行输入touch whale.txt
,然后在命令行使用cwl-runner inp.cwl inp-job.yml
命令,用工具包装器和输入对象调用cwl-runner
。 下面描述了这两个命令以及命令行的输出:
$ touch whale.txt
$ cwl-runner inp.cwl inp-job.yml
[job inp.cwl] /tmp/tmpzrSnfX$ echo \
-f \
-i42 \
--example-string \
hello \
--file=/tmp/tmpRBSHIG/stg979b6d24-d50a-47e3-9e9e-90097eed2cbc/whale.txt
-f -i42 --example-string hello --file=/tmp/tmpRBSHIG/stg979b6d24-d50a-47e3-9e9e-90097eed2cbc/whale.txt
[job inp.cwl] completed success
{}
Final process status is success
那些
/tmp
路径是从哪里来的?The CWL reference runner (cwltool) 和其他runners 通过软链接输入文件到创建的临时目录。以确保工具不会意外地访问未明确指定的文件
字段是可选的,它表示输入参数是否出现以及如何出现在工具的命令行上。 如果缺少inputBinding
,则该参数不会出现在命令行中。
让我们看看每个例子的细节。
example_flag:
type: boolean
inputBinding:
position: 1
prefix: -f
类型被视为标记。 如果输入参数“ example flag”为“ true” ,则prefix
将被添加到命令行。 如果 false,则不添加任何标记。
example_string:
type: string
inputBinding:
position: 3
prefix: --example-string
类型作为文本值出现在命令行上。 prefix
是可选的,如果提供了 prefix
,它将作为一个单独的参数出现在命令行的参数之前。 在上面的例子中,它被渲染为 --example-string hello
。
example_int:
type: int
inputBinding:
position: 2
prefix: -i
separate: false
(和浮点数)类型出现在带有十进制文本形式表示的命令行上。 当选项separate
为 false (默认值为 true)时,前缀和值组合成一个参数。 在上面的例子中,这被渲染为-i42
。
example_file:
type: File?
inputBinding:
prefix: --file=
separate: false
position: 4
类型作为文件的路径出现在命令行上。 当参数类型以问号?
结尾时。 这表明参数是可选的。 在上面的例子中,它被渲染为--file=/tmp/random/path/whale.txt
。 但是,如果输入中没有提供“ example file”参数,则命令行上将不会显示任何内容。
输入文件是只读的。 如果你想更新一个输入文件,你必须先将它复制到输出目录
position
的值用于确定参数应该出现在命令行的哪个位置。 位置是相对的,不是绝对的。 因此,位置不一定是连续的。如,位置为1,3,5的三个参数和1,2,3将产生同一个命令行。 多个参数可以具有相同的位置(使用参数名称断开关系) ,并且位置字段是可选的。 默认位置是0。
The baseCommand
字段总是出现在参数之前的最后一行命令中。
总结
- CWL的
inputs
部分描述了输入。 - 文件应该用
class: File
来描述。 - 使用
inputBinding
部分来描述input在命令中出现的位置和方式。
四、返回输出文件
工具的outputs
是运行工具后应返回的输出参数列表。 每个参数都有一个id
,type
描述哪些类型的值对该参数有效。
当某个工具在 cwl 下运行时,起始的工作目录是一个指定的输出目录。 底层工具或脚本必须在输出目录中以创建文件的形式记录其结果。 CWL 工具返回的输出参数要么是输出文件本身,要么是检查这些文件的内容。
下面的示例演示如何返回从 tar 文件中提取的文件。
给
baseCommand
传递强制性的参数在前面的例子中,
baseCommand
只是一个字符串,任何参数都可以作为 cwl 输入传递。 如果不是单一的字符串,我们可以使用 数组字符串。 第一个元素是要运行的命令,后面都是必需的命令行参数
tar.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: [tar, --extract]
inputs:
tarfile:
type: File
inputBinding:
prefix: --file
outputs:
example_out:
type: File
outputBinding:
glob: hello.txt
tar-job.yml
tarfile:
class: File
path: hello.tar
接下来,为这个例子创建一个 tar 文件,并在命令行中调用cwl-runner
$ touch hello.txt && tar -cvf hello.tar hello.txt
$ cwl-runner tar.cwl tar-job.yml
[job tar.cwl] /tmp/tmpqOeawQ$ tar \
--extract --file \
/tmp/tmpGDk8Y1/stg80bbad20-494d-47af-8075-dffc32df03a3/hello.tar
[job tar.cwl] completed success
{
"example_out": {
"location": "file:///home/me/cwl/user_guide/hello.txt",
"basename": "hello.txt",
"class": "File",
"checksum": "sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709",
"size": 0,
"path": "/home/me/cwl/user_guide/hello.txt"
}
}
Final process status is success
字段描述了如何设置每个输出参数的值。
outputs:
example_out:
type: File
outputBinding:
glob: hello.txt
glob
字段由输出目录中的文件名组成。 如果事先不知道文件名,可以使用通配符模式,比如glob: '*.txt'
。
总结
- 输出在 cwl 的
outputs
部分。 -
outputBinding
字段描述了如何设置每个输出参数的值。 -
glob
字段中可以使用通配符。
五、捕获标准输出
要捕获工具的标准输出流,请添加stdout
字段,其中包含输出流所在的文件名。 然后在相应的输出参数上添加type: stdout
。
stdout.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
stdout: output.txt
inputs:
message:
type: string
inputBinding:
position: 1
outputs:
example_out:
type: stdout
echo-job.yml
message: Hello world!
调用cwl-runner
$ cwl-runner stdout.cwl echo-job.yml
[job stdout.cwl] /tmp/tmpE0gTz7$ echo \
'Hello world!' > /tmp/tmpE0gTz7/output.txt
[job stdout.cwl] completed success
{
"example_out": {
"location": "file:///home/me/cwl/user_guide/output.txt",
"basename": "output.txt",
"class": "File",
"checksum": "sha1$47a013e660d408619d894b20806b1d5086aab03b",
"size": 13,
"path": "/home/me/cwl/user_guide/output.txt"
}
}
Final process status is success
Key Points
- 使用
stdout
字段指定捕获流输出的文件名。 - 相应的输出参数必须有
type: stdout
。
网友评论