Skip to content

CWL Start Guide JP

Tazro Inutano Ohta edited this page Oct 18, 2018 · 17 revisions

このドキュメントは何?

このドキュメントは、Common Workflow Language (以下、CWL) について興味を持っている人に、CWLとはどんなもので、何を目的とした道具であるかを、15分で説明するためのドキュメントです。CWLの仕様の解説や、チュートリアルの提供を目的としたものではありません。

誰が書いているの?

Pitagora Project のメンバーである、科学データ解析に携わる研究者と開発者です。このドキュメントについてのご意見ご感想や、CWLについて分からないことがあれば、Google フォーム から送ってください。もしくは、 Twitter でハッシュタグ #CommonWLjp を付けてつぶやいてください

想定読者

  • 業務や研究でデータ解析ワークフローを使う、もしくは作る人
  • ワークフローを実行するためのソフトウェア (実行エンジン) を設計する人

15分は長いという人へ

64秒での解説がこちら (日本語字幕つき)

CWL とは?

ソフトウェアを組み合わせて構成される一連の作業手順 (ワークフロー) を記述するための仕組みや言語、GUI ソフトウェアは既に多く存在します。しかし、それらは特定の実行環境 (ハードウェア、ソフトウェア) に依存したものであり、異なる環境の間でワークフローを共有、再実行することは困難です。この問題を解決するために、異なるワークフロー実行ソフトウェア (実行エンジン) の間で共通してインポート/エクスポートできるフォーマットを目指して、Common Workflow Language (CWL) の開発が始まりました。

CWL は Bioinformatics Open Source Conference (BOSC) 2014 Codefest の参加者によって立ち上げられた、特定の企業や大学、研究室、グラントに依存しない、オープンソースプロジェクトです。現在も、主に生命科学系の企業や大学の研究者の貢献によって GitHub, gitter などでコミュニケーション、議論、開発が進行しています。CWL自体は、生命科学系に限定されることなく、どの分野でも利用できる汎用的なものです。

以下に、CWL を使ってどのようにワークフローを記述するかを紹介します。

CWL 記述形式

CWL では、ソフトウェア (コマンドラインツール) とワークフローの内容を YAML もしくは JSON の形式で記述し、.cwl という拡張子でファイルに保存します。実行時には、この CWL ファイルと、必要に応じて実行時パラメータを、CWL をサポートしている実行エンジンに入力すると、ワークフローが実行されます。

CWL で書いてみる: コマンドラインツール

(このパートは http://www.commonwl.org/user_guide/02-1st-example/ の内容を反映しています)

Hello World を表示するツールを CWLで記述します。bash であれば、以下のコマンドです。

$ echo "Hello World"
Hello World

この処理を CWL で記述してみます。

cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs:
  message:
    type: string
    inputBinding:
      position: 0
outputs:
 hello_output:
   type: stdout
stdout: hello-out.txt

このファイル hello.cwl を CWL に対応している実行エンジンに入力すると、ツールが実行されます。CWL の標準実装である、cwltool の場合には以下のようになります。

$ cwltool helloworld.cwl --message 'Hello World'

以下、実行結果です。

$ cwltool helloworld.cwl --message 'Hello World'
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'helloworld.cwl' to 'file:///home/vagrant/hajimete/helloworld.cwl'
[job helloworld.cwl] /tmp/tmpPNAUDo$ echo \
    'Hello World' > /tmp/tmpPNAUDo/hello-out.txt
[job helloworld.cwl] completed success
{
    "hello_output": {
        "checksum": "sha1$648a6a6ffffdaa0badb23b8baf90b6168dd16b3a",
        "basename": "hello-out.txt",
        "location": "file:///home/vagrant/hajimete/hello-out.txt",
        "path": "/home/vagrant/hajimete/hello-out.txt",
        "class": "File",
        "size": 12
    }
}
Final process status is success

出力結果を確認します。

$ cat hello-out.txt
Hello World

以下に、CWL ファイルを各パートごとに解説します。

cwlVersion: v1.0

cwlVersion キーワードで、準拠しているCWLのバージョンを記述します。

class: CommandLineTool

class キーワードで、これが単独のツールを実行する (ワークフローではない) コマンドラインツールであることを示す CommandLineTool を指定します。

baseCommand: echo

baseCommand で 実行されるコマンドを指定します。この場合は echo コマンドです。

inputs:
  message:
    type: string
    inputBinding:
      position: 0

inputs キーワードで、コマンドに与える入力について記述します。ここでは message という名前をつけて1つのコマンド入力を定義しています。message には echo コマンドに与える文字列が入るので、 type キーワードで入力データの型 string を指定します。inputBinding キーワードを使って、 baseCommandmessage がどのように渡されるかを指定します。ここでは、position キーワードを使って、コマンドライン上の echo コマンドの直後 (0番目) に message が渡されるように定義します。

outputs:
 hello_output:
   type: stdout

outputs キーワードで、コマンドから得る出力について記述します。ここでは hello_output という名前をつけて、1つの出力を得ます。hello_output は標準出力に書き込まれる文字列を得たいので type キーワードで stdout を指定します。

stdout: hello-out.txt

stdout キーワードで、標準出力を取得します。stdout: hello-out.txt によって、標準出力に出た文字列を hello-out.txt というファイルに書き込みます。

CWL で書いてみる: ワークフロー

下図の処理を実行するワークフローを CWL で記述します。この処理では入力ファイル(file_to_search) から特定のパターン (pattern) を含む行数を grep コマンドで抽出し、その出現回数を wc コマンドでカウントします。wc の結果 (counts) がワークフローの出力です。

workflow_grep-and-wc

例として、以下のテキストを保存した mock.txt から、パターン one が含まれる行の出現回数を調べます。

one
two
one
three

bash では以下のように行います。

$ grep one mock.txt > grepout.txt
$ wc -l grepout.txt > wcout.txt
$ cat wcout.txt
2

このワークフローを CWL として記述する前に、以下のように grep と wc を実行する CWL をそれぞれ記述します。

cwlVersion: v1.0
class: CommandLineTool
baseCommand: grep
inputs:
  pattern:
    type: string
    inputBinding:
      position: 0
  file_to_search:
    type: File
    inputBinding:
      position: 1
outputs:
  results: stdout
stdout: grepout.txt
cwlVersion: v1.0
class: CommandLineTool
baseCommand: [wc, -l]
inputs:
  file:
    type: File
    inputBinding:
      position: 0
outputs:
  counts: stdout
stdout: wcout.txt

次に、この2つのコマンドラインツールを使い、grep をして wc をするワークフローを作成します。

cwlVersion: v1.0
class: Workflow
inputs:
  grep_pattern:
    type: string
  target_file:
    type: File
outputs:
  counts:
    type: File
    outputSource: wc/counts
steps:
  grep:
    run: grep.cwl
    in:
      pattern: grep_pattern
      file_to_search: target_file
    out: [results]
  wc:
    run: wc.cwl
    in:
      file: grep/results
    out: [counts]

このワークフローを、cwltool を使って実行してみます。

$ cwltool grep-and-count.cwl --target_file mock.txt --grep_pattern one

実行するとこのようになります。

$ cwltool grep-and-count.cwl --target_file mock.txt --grep_pattern one
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'grep-and-count.cwl' to 'file:///home/vagrant/cwl-samples/grep-and-count.cwl'
[workflow grep-and-count.cwl] start
[step grep] start
[job grep] /tmp/tmpH0lrD9$ grep \
    one \
    /tmp/tmplmLMRE/stga2fed2a1-73d3-4739-8a71-a3bff07a210b/mock.txt > /tmp/tmpH0lrD9/grepout.txt
[job grep] completed success
[step grep] completed success
[step wc] start
[job wc] /tmp/tmpsV7RZO$ wc \
    -l \
    /tmp/tmp74O9fg/stg92157e74-dce3-4ea2-beaf-725d6390249e/grepout.txt > /tmp/tmpsV7RZO/wcout.txt
[job wc] completed success
[step wc] completed success
[workflow grep-and-count.cwl] completed success
{
    "counts": {
        "checksum": "sha1$3d069f5c2f47dd7b91490991378518c18ec84e86",
        "basename": "wcout.txt",
        "location": "file:///home/vagrant/cwl-samples/wcout.txt",
        "path": "/home/vagrant/cwl-samples/wcout.txt",
        "class": "File",
        "size": 69
    }
}
Final process status is success

実行結果を確認します。

$ cat wcout.txt
2 /tmp/tmpYg7Goq/stg73ea3c6a-5ac1-4a63-94ad-4eaed213ab82/grepout.txt

mock.txtの中にある。 'one' という文字列が含まれている行数が、 2 であることが確認できます。

以下、ワークフロー記述を各パートごとに解説します。

cwlVersion: v1.0

CommandLineTool と同じく、 cwlVersion キーワードで準拠している CWL ツールのバージョンを記述します。

class: Workflow

class キーワードで、ツールを組み合わせた Workflow であることを記述します。

inputs:
  grep_pattern:
    type: string
  target_file:
    type: File

inputs キーワードで、ワークフロー全体の入力を記述します。ここでは、 pattern, file_to_search と名前をつけた 2つの入力があることを示します。それぞれ、string, File と型を指定します。

outputs:
  counts:
    type: File
    outputSource: wc/counts

outputs キーワードで、ワークフロー全体の出力を記述します。counts と名前をつけて、wcコマンドの出力を得るよう指定します。 typeFile です。 outputSource キーワードを使って、後述の steps 内の wc における出力 counts を取得するよう、 wc/counts と記述します。

steps:
  grep:
    run: grep.cwl
    in:
      pattern: grep_pattern
      file_to_search: target_file
    out: [results]
  wc:
    run: wc.cwl
    in:
      file: grep/results
    out: [counts]

(stepは、ワークフローとしての識別子と、ツールとしての識別子がでてきており、頭の中でマッピングしながら理解する必要があり、大変です。これを書いた人たちもつらかったです。しかし、CWLの肝なので、落ち着いてゆっくりと何度も大きく声に出して読んでください。図も見ながら読むと理解の手助けになります。)

steps キーワードで、ワークフローの各ステップを記述します。各 step は自由に名前をつけられますが、ここでは grepwc としました。各 step では、 run キーワードで、それぞれの CommandLineTool を記述した CWL ファイルのファイル名を指定します。また、inout のキーワードを使って、各ステップの入力、出力を指定します。

最初に実行される grep の入力は、ワークフロー全体の入力を受け取るため、前述の grep_patterntarget_file を指定します。pattern: grep_pattern において、grep.cwl 内で定義された入力 pattern に、grep-and-count.cwl における入力 grep_pattern を与えることを示しています。file_to_search: target_file も同様です。out では、 grep.cwl 内で定義された results を指定します。この場合のみ、[] で囲む必要があります。

次に実行される wc の入力は、grep の出力 results を受け取るため、grep/results と記述します。ここでも同じく、 wc.cwl で定義された counts を取得するため [counts] と記述します。

CWL で書けること

ツール定義は主に、実行コマンド定義、入力定義、出力定義および動作要件定義(オプション)から構成されます。実行コマンド定義では実行するプログラム名や Docker のイメージ名を指定することができます。入力定義では各入力の型や引数として与える順序を指定できます。出力定義ではツールの出力として、標準出力や出力ファイル名を指定します。動作要件指定では、搭載メモリ量の下限など、コマンドを実行するために必要な条件を指定できます。

ワークフロー定義は主に、ツール定義と同様の入出力定義および各ステップの定義から構成されます。各ステップの入力として他のステップの出力を指定することで、ステップ間の依存関係を記述します。

CWL で書けないこと

CWL v1.0 では、ループや条件分岐の記述をサポートしていません。ただし CWL への機能追加は現在も議論されており、将来的にサポートされる可能性はあります。また各ステップの並列処理や、使用するジョブスケジューラの指定等も CWL ではサポートしていません。実行エンジンによっては、別途サポートしていることがあります。

付属情報

その他 CWL 記述の例

http://www.commonwl.org/#Repositories_of_CWL_Tools_and_Workflows に、GitHub などで公開されている CWL 記述へのリンクがあります。

CWL Reference Implementation について

CWL の仕様を満たす標準実装として、cwltool というワークフロー実行エンジンが CWL と合わせて開発されています (https://github.com/common-workflow-language/cwltool)。高機能ではありませんが、CWL を入力としてワークフローの実行ができます。頻繁に更新されるため、実運用には注意が必要です。

CWL を受け付ける実行エンジン

http://www.commonwl.org/#Implementations に、CWL のインポート・エクスポートに対応している実行エンジンのリストがあります。

CWL に関連するソフトウェア

http://www.commonwl.org/#Software_for_working_with_CWL に、CWL の可視化、エディタのサポート、各種プログラミング言語のバインディングなどのリストがあります。

CWL について興味が出てきた、次になにをしたらよい?

公式のユーザーガイド http://www.commonwl.org/user_guide/ があるので、そちらをやってみるとよいでしょう。3時間位あれば一通りのことができます。

CWL に関連する有益なリンクのリスト

FAQ はこちら

FAQ