1

初期ワークフロー

ペアエンド データから出力を生成できるスネークファイルがあります。

このスネークファイルには、構成ファイル ( 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 を正しいルールに導くには明らかに不十分です。

4

2 に答える 2

1

役立つかどうかはわかりませんが、関数を使用してルールの入力を定義できます。このようにして、ルールの出力が同じであれば、同じルールを使用してシングルエンド データまたはペアエンド データのいずれかを処理できます...

def my_inputs(wildcards):
    data_type = config["data_type"]
    if (data_type == "pe"):
        input = ...
    elif (data_type == "se"):
        input = ...
    return input

rule my_rule:
    input: my_inputs
    ...
于 2016-11-09T16:00:10.553 に答える
0

user1829905が提案したように、ルールを 1 つにしようとしましたget_raw_data*が、このルールの出力が可変であるために失敗しました。

ただし、run_tophat*ルールを 1 つに融合することができます。これらのルールは同じ出力を持ちます。

rule run_tophat:
    input:
        transcriptome = OPJ(annot_dir, "dmel-all-r5.9.gff"),
        fq = lib2fq,
    output:
        junctions = OPJ(output_dir, "{lib}", "junctions.bed"),
        bam = OPJ(output_dir, "{lib}", "accepted_hits.bam"),

この融合ルールの入力を生成するために、次の関数を試しました。

def lib2fq(wildcards):
    lib = wildcards.lib
    if lib in lib2sr:
        return [OPJ(raw_data_dir, "{lib}_1.fastq.gz"), OPJ(raw_data_dir, "{lib}_2.fastq.gz")]
    elif lib in lib2raw:
        return [OPJ(raw_data_dir, "{lib}_1.fastq.gz"), OPJ(raw_data_dir, "{lib}_2.fastq.gz")]
    elif lib in lib2raw_single_end:
        return [OPJ(raw_data_dir, "{lib}.fastq.gz")]
    else:
        raise ValueError("Procedure to get raw data for %s unknown." % lib)

しかし、この試みは次の理由で失敗しましたInputFunctionException:

ValueError: Procedure to get raw data for {lib} unknown.

ただし、最初のルールの出力に関して明示的に定義された 2 番目のルールの入力を作成すると、問題は解決します。

def lib2fq(wildcards):
    lib = wildcards.lib
    if lib in lib2raw_single_end:
        return rules.get_raw_data_single_end.output
    else:
        return rules.get_raw_data.output

この違いの理由がよくわかりません。

于 2016-11-09T18:04:00.020 に答える