初期ワークフロー
ペアエンド データから出力を生成できるスネークファイルがあります。
このスネークファイルには、構成ファイル ( get_raw_data
) に格納されている情報を指定してデータを「インストール」するルールがあります。
次に、そのデータを使用して、残りのワークフローが依存する中間ファイルを生成するルールを作成します ( run_tophat
)。
これらのルールの入力と出力は次のとおりです (OPJ
は を表しますos.path.join
)。
rule get_raw_data:
output:
OPJ(raw_data_dir, "{lib}_1.fastq.gz"),
OPJ(raw_data_dir, "{lib}_2.fastq.gz"),
(このルールの実装については後で詳しく説明します)
rule run_tophat:
input:
transcriptome = OPJ(annot_dir, "dmel-all-r5.9.gff"),
fq1 = OPJ(raw_data_dir, "{lib}_1.fastq.gz"),
fq2 = OPJ(raw_data_dir, "{lib}_2.fastq.gz"),
output:
junctions = OPJ(output_dir, "{lib}", "junctions.bed"),
bam = OPJ(output_dir, "{lib}", "accepted_hits.bam"),
そして(単純化すると)私の主なルールは次のようになります。
rule all:
input:
expand(OPJ(output_dir, "{lib}", "junctions.bed"), lib=LIBS),
ワークフローをシングルエンド データに拡張する
シングルエンドのデータに対してワークフローを実行する必要があります。
データがシングルエンドかペアエンドかによって、最終出力の名前パターンが異なることは避けたいと思います。
入力と出力が次のようなシングルエンド データ (get_raw_data_single_end
および) で機能する、上記の 2 つのルールのバリアントを簡単に作成できます。run_tophat_single_end
rule get_raw_data_single_end:
output:
OPJ(raw_data_dir, "{lib}.fastq.gz")
rule run_tophat_single_end:
input:
transcriptome = OPJ(annot_dir, "dmel-all-r5.9.gff"),
fq = OPJ(raw_data_dir, "{lib}.fastq.gz"),
output:
junctions = OPJ(output_dir, "{lib}", "junctions.bed"),
bam = OPJ(output_dir, "{lib}", "accepted_hits.bam"),
正しいルールパスを選択するのに十分な情報をsnakemakeに提供するにはどうすればよいですか?
lib
構成ファイルには、ワイルドカードが次の方法でシングルエンド データまたはペアエンド データに関連付けられているかどうかに関する情報が含まれています。ライブラリ名は、lib2raw
またはlib2raw_single_end
辞書のキーです (両方の辞書は構成ファイルから読み取られます)。
同じライブラリ名が両方の辞書のキーになるとは思っていません。したがって、ワークフローのシングルエンド分岐とペアエンド分岐のどちらを実行してほしいかは、ある意味で曖昧ではありません。
関数lib2data
(これらの辞書を使用する) は、 と の両方get_raw_data
で使用されget_raw_data_single_end
、データを「インストール」するために実行するシェル コマンドを決定します。
以下は、この関数の簡略化されたバージョンです (実際の関数には、SRR 識別子からデータのコマンドを生成するための追加のブランチが含まれています)。
def lib2data(wildcards):
lib = wildcards.lib
if lib in lib2raw:
raw = lib2raw[lib]
link_1 = "ln -s %s %s_1.fastq.gz" % (raw.format(mate="1"), lib)
link_2 = "ln -s %s %s_2.fastq.gz" % (raw.format(mate="2"), lib)
return "%s\n%s\n" % (link_1, link_2)
elif lib in lib2raw_single_end:
raw = lib2raw_single_end[lib]
return "ln -s %s %s.fastq.gz\n" % (raw, lib)
else:
raise ValueError("Procedure to get raw data for %s unknown." % lib)
出力を除けば、2 つのget_raw_data*
ルールは同じであり、次のように機能します。
params:
shell_command = lib2data,
shell:
"""
(
cd {raw_data_dir}
{params.shell_command}
)
"""
ルールの入力と出力ではコード化されておらず、構成ファイルと関数でのみコード化されている情報が与えられた場合、snakemake は正しいルール パスを決定できますか?
そうではないようです。実際、新しいスネークファイルをテストしようとしています (*_single_end
ルールを追加して)、ただし、ルール.KeyError
の実行中に発生しますがget_raw_data
、ルールが実行されているライブラリはシングルエンド データに関連付けられています。
目的の動作を実現するにはどうすればよいですか (構成内の情報を使用して正しいブランチを選択できる 2 つのブランチのワークフロー)。
編集:KeyError
エラーが原因でしたlib2data
正しい辞書を使用してライブラリ名に関連付けられたデータを取得した後、次のエラーが発生します。
AmbiguousRuleException:
Rules run_tophat and run_tophat_single_end are ambiguous for the file tophat_junction_discovery_revision_supplement/HWT3/junctions.bed.
Expected input files:
run_tophat: ./HWT3_1.fastq.gz ./HWT3_2.fastq.gz Annotations/dmel-all-r5.9.gff
run_tophat_single_end: ./HWT3.fastq.gz Annotations/dmel-all-r5.9.gff
get_raw_data*
編集 2:ルールへの入力の追加
snakemake メーリング リストでこの投稿を読んだ後、あいまいさを避けるためにルールに入力を追加しようとしました。
def lib2data_input(wildcards):
lib = wildcards.lib
if lib in lib2raw:
raw = lib2raw[lib]
return [raw.format(mate="1"), raw.format(mate="2")]
elif lib in lib2raw_single_end:
raw = lib2raw_single_end[lib]
return [raw]
else:
raise ValueError("Procedure to get raw data for %s unknown." % lib)
rule get_raw_data:
input:
lib2data_input
# [same output, params and shell as before]
# [same modification for the single-end case]
これにより、(これを再現することはできません。現在は次のようになります:)MissingInputException
. 不思議なことに、欠落していると報告されているファイルが存在します。トリックは機能するはずですか?
AmbiguousRuleException:
Rules run_tophat_single_end and run_tophat are ambiguous for the file tophat_junction_discovery_revision_supplement/HTW2/junctions.bed.
Expected input files:
run_tophat_single_end: ./HTW2.fastq.gz Annotations/dmel-all-r5.9.gff
run_tophat: ./HTW2_1.fastq.gz ./HTW2_2.fastq.gz Annotations/dmel-all-r5.9.gff
「データ インストール」ルールへの入力を指定する私の方法は、snakemake を正しいルールに導くには明らかに不十分です。