Edited at

雑に始める CWL!


はじめに

真面目に CWL を書いてみたい場合には、公式で提供している User Guide や、日本の CWL コミュニティが公開している CWL ファイルが参考になると思います。

この記事ではそうではなく、「CWL の細かい文法とかどうでもいい。とりあえず今動いてるツールをそれっぽく CWL 化して CWL のワークフローから使えるようにしたい」という方向けに、できるだけ細かい文法要素に踏み込まずにツールの定義ファイルを CWL で書く例を示します。


注意


  • 本記事では、ツールのオプションをうまいこと扱う方法については書きません。様々なオプションを入力パラメータとして与えたい場合には、まじめに CWL を書きましょう。


CWL 化したいツール

以下のツールの定義ファイルを CWL で書くことを考えます。

このコマンドは、引数で与えられたファイルの先頭数行を、標準出力に表示します。

出力する行数は -n で与えられます。

$ head -n5 foobar.txt



  • -n55 と、foobar.txt を入力パラメータとして与えたい。


  • head コマンドの標準出力を、ツールの出力オブジェクトとして取得できるようにしたい。

  • 他のオプションは知らぬ。


ツール自体の動作サンプル

$ man head > manhead.txt

$ head -n5 manhead.txt

HEAD(1) BSD General Commands Manual HEAD(1)

NAME
head -- display first lines of a file


作成


  • まず以下を head.cwl としてコピーします。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: []
arguments: []
inputs: []
outputs: []



  • baseCommand に、先程のコマンドの先頭部分、それ以降を arguments に追加します。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n5, foobar.txt]
inputs: []
outputs: []


  • 入力パラメータを inputs に追加します。今回は表示したいファイルである source、先頭 n 行を表す nlines を導入します。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n5, foobar.txt]
inputs:
- id: source
- id: nlines
outputs: []


  • 各入力パラメータに型を追加します。source はファイルなので Filenlines は整数値を取るので int です。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n5, foobar.txt]
inputs:
- id: source
type: File
- id: nlines
type: int
outputs: []



  • arguments5foobar.txt が残ったままなので、それぞれ nlinessource の値に置き換えるようにします。これは $(inputs.idフィールド名) という記法で実現できます。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n$(inputs.nlines), $(inputs.source)]
inputs:
- id: source
type: File
- id: nlines
type: int
outputs: []


  • 出力パラメータを追加します。今回はとりあえず out という名前をつけます。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n$(inputs.nlines), $(inputs.source)]
inputs:
- id: source
type: File
- id: nlines
type: int
outputs:
- id: out


  • 入力パラメータの時と同様に、出力パラメータに型を付けます。標準出力を取得したい場合には stdout 型を使えばいいです。


head.cwl

cwlVersion: v1.0

class: CommandLineTool
baseCommand: [head]
arguments: [-n$(inputs.nlines), $(inputs.source)]
inputs:
- id: source
type: File
- id: nlines
type: int
outputs:
- id: out
type: stdout


  • できあがり!


動かしてみる

試しに sourcemanhead.txtnlines5 の場合を試してみます。

$ man head > manhead.txt

$ cwltool head.cwl --source manhead.txt --nlines 5
...
[job head.cwl] completed success
{
"out": {
"location": "file:///Users/tom-tan/147d6ad946430f35c2aafbff6c5604d43b30aa14",
"basename": "147d6ad946430f35c2aafbff6c5604d43b30aa14",
"class": "File",
"checksum": "sha1$30c2a20de147871db76e237705ac274277504428",
"size": 145,
"path": "/Users/tom-tan/147d6ad946430f35c2aafbff6c5604d43b30aa14"
}
}
Final process status is success
$ cat 147d6ad946430f35c2aafbff6c5604d43b30aa14

HEAD(1) BSD General Commands Manual HEAD(1)

NAME
head -- display first lines of a file



  • [job head.cwl] completed success 以下に、出力オブジェクトが表示されます。


    • 今回の場合、out として 147d6ad9464... という名前のファイルオブジェクトがあるのがわかります。



  • 実際に cat コマンドで確認すると、ツール自体の動作サンプルと同様の内容が得られたことがわかります。


次のステップ


出力ファイル名がひどい

stdout フィールドで標準出力を保存するファイル名を指定できます。


head.cwl

...

outputs:
- id: out
type: stdout
stdout: output.txt # この行を追加


source のファイル名が manhead.txt の時には、出力ファイル名を manhead-head.txt にしたい

$() 記法を活用すればいいです。File オブジェクトの nameroot フィールドを使うことで、manhead.txt から manhead のみを取り出すことができます。


head.cwl

...

outputs:
- id: out
type: stdout
stdout: $(inputs.source.nameroot)-head.txt # この行を変更


Docker で動かしたい

DockerRequirement というものを使います。またdockerPull で、利用したい docker イメージ名を指定します。


head.cwl

...

outputs:
- id: out
type: stdout
stdout: $(inputs.source.nameroot)-head.txt
# 以下を追記
requirements:
- class: DockerRequirement
dockerPull: debian:latest

volume mount などの細かい部分は、CWL の処理系がうまいことやってくれます。


おわり

今回はツール定義を CWL で書く方法を示しました。

これで CWL 書き放題ですね!!!


おまけ

続編書きました。