9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Snakemake チートシート

Last updated at Posted at 2019-08-31

Snakemake 公式 | Snakemake GitHub

Snakemake は、GNU Make のようなタスクランナーの一つです。ファイルの依存関係をシンプルに書きつつ、Python で好きな処理がかけるのが魅力です。

ルールの書き方

rule all:
    input: "output-A.txt"

rule hoge:
    input: "input-{sample}.txt"
    output: "output-{sample}.txt"
    shell: "myscript.sh {input} > {output}"
パラメータ 説明
input: 入力ファイルの指定。{sample} 等でワイルドカードを指定できる。
output: 出力ファイルの指定。input: の指定したワイルドカードを使うことができる。
shell: 実行するコマンド。{input}, {output} などを利用可。
run: 実行するPythonコード。shell:run: は同時に指定できない。

その他のパラメータ: params:, log:, benchmark:, message:, threads:, resources:, version:,

リファレンス

定義済み変数

input: 以外のパラメータでは {input}, {output} などとして定義済み変数にアクセスできる。トップレベルのコード部や run: パラメータでは、通常の変数としてアクセス可。

変数 説明
{input} input:に対応するファイル、またはファイル群(スペース区切り)
{output} output:に対応するファイル、またはファイル群(スペース区切り)
{wildcards.*} input:, output: で指定したワイルドカードの集まり。
{params.*} params: で設定した文字列の集まり。
{rules.*} 定義された rule: の集まり。
{checkpoints.*} 定義された checkpoint: の集まり。
{config} configfile: で読み込んだファイルの設定。
{rule} ( shell:, run: のみアクセス可。)現在のルール名(str)

{.*} となっている箇所は、{wildcards.sample}等、属性に個々のアイテム名を指定する。

input: では {hoge} とした部分はすべてワイルドカード定義として扱われる。

定義済みトップレベル要素

rule: 以外にも、下記の要素を定義することができます。その他、通常の Python コードを記述することが可能です。

要素 説明
rule: ルール指定(前述)
checkpoint: 特殊なルール指定(使い方は後述)
configfile: YAML 形式の外部変数定義を読み込む。
include: 他の Snakefile を取り込む
workdir: カレントディレクトリを指定
subworkflow: (未調査)

定義済み関数(抜粋)

関数 説明
expand wildcard を展開した結果の str のリストを返す。最終成果物のリストの生成などで頻繁に使うことになる(はず)。
glob_wildcards ファイル名探索をする glob のワイルドカード版。得られるのが、ファイル名ではなく、ワイルドカードであることに注意。(普通にファイル名の一覧が必要であれば標準ライブラリ(`glob.glob`等)を普通に使える)
touch output: セクションで使用。処理完了後に touch で指定されたファイルの更新時刻を更新する。
directory output: セクションで使用。出力先としてディレクトリを指定するときに使用。参考
temp output: セクションで使用。引数で指定されたファイルは、ジョブ成功時でも削除される。
protected output: セクションで使用。引数で指定されたファイルは、ジョブ失敗時にも削除されない。
remote input:, output: セクションで使用。詳細は別ページで説明予定

ワイルドカードの書式

書式 説明
{sample} デフォルト。正規表現としては .+ が指定されたのと同じ
{sample,[A-Z]+} ,の後ろにワイルドカードがマッチする正規表現を指定可能
{sample:02d} Python標準のフォーマット指定も利用可
{sample:q} 文字列をクォートする

コマンドラインオプション

オプション 説明
-n, --dryrun dryrun
-p, --printshellcmds 実行したコマンドを標準出力に出す(デフォルトでは出ない)
-f, --force 依存関係を無視して強制実行する
-R [TARGET, TARGET, ...], --forcerun [TARGET, TARGET, ...] TARGET 以降のルール(TARGET と、TARGET に依存しているルール)を再実行する
-U TARGET[, TARGET, ...], --until TARGET[, TARGET, ...] TARGET 以前のルール (TARGET が依存しているルール) を再実行する
-s filename, --snakefile filename Snakefile を指定
-d, --directory ワーキングディレクトリを指定
-l, --list Snakefile の rule 一覧を出力する
--lt, --list-target-files rule のうち、snakemake RULE として指定可能なルール (=ルールにwildcardを含まないもの) を出力する。なお、-lt とすると、-l, -t(--touch) と解釈され、--lt とはならないので注意。
-t, --touch outputのファイルの更新時間だけを更新し、コマンドを実行しない。output のファイルがない場合には何も起こらないことに注意(空ファイルが作成されたりはしない)
-k, --keep-going 途中でエラーが発生しても、実行可能なジョブは実行する(デフォルトはエラー発生次第、即座に止まる)

定番の書き方

default ターゲット

ターゲット指定が省略された場合、Make と同じく一番上の rule がターゲットとして指定された扱いになる。

input: に、最終的に生成されるファイルを指定することで、必要な依存関係をたどって生成に必要な rule: 群が実行される。

rule all:
    input: "final-result.txt"

分析の途中から再実行

ワイルドカード付きのルールを再実行したい場合、-R (--forcerun) オプションを使います。

% snakemake -R step2 all

最終的にワイルドカードを展開しているルールを指定しつつ、 -R オプションで再実行するターゲットを指定します。

単に -f オプションで指定すると、ワイルドカードの展開ができずエラーになります。

% snakemake -f step2
Building DAG of jobs...
WorkflowError:
Target rules may not contain wildcards. Please specify concrete files or a rule without wildcards.

参考 Can SnakeMake be forced to rerun rules when files are missing - Stack Overflow

分析の特定ステップだけを再実行

先程の例は step2 以降を再実行でしたが、step2 だけを再実行したい場合はどうでしょうか。その場合は -U オプションを利用します。

% snakemake -R step2 -U step2 all

ちょうど -R で指定したターゲットから、-Uで指定したターゲットまでが実行されます。両方に同じターゲットを指定すると、そのターゲットだけが実行されるようになります。

.env の読み込み

Snakefile には通常の Python スクリプトを書けますので1、たとえば pip install python-dotenv を実行しておいて、Snakefile

Snakefile
from dotenv import load_dotenv

load_dotenv()

# 以後、通常のルール記述
rule all:
    input: ...

などと書けばOKです。

(逆にいえば、snakemake 標準では .env の読み込み機能は提供されていない模様。)

input: パラメータに変数の値を指定する

var_a = 'some_text'

rule hoge:
    input: "{var_a}"

などと書いても、{var_a} というワイルドカードを定義したことになり、変数の値は入りません。変数の値をいれるためには、例えば下記の方法があります。

  1. input: f'{var_a}' とする。(ワイルドカードを使う場合は f'{var_a}-{{wc_a}}' とワイルドカード側を {{}} とする。)
  2. input: expand('{var_a}', var_a=var_a) として、ワイルドカード展開を利用する
  1. 正確には「ルール記述が通常の Python 関数に置き換えられて、Python スクリプトとして実行される」

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?