5

次のファイルがあり、snakemake を使用して自動的に処理を適用したいとします。

test_input_C_1.txt
test_input_B_2.txt
test_input_A_2.txt
test_input_A_1.txt

次のスネークexpandファイルは、潜在的な最終結果ファイルをすべて決定するために使用します。

rule all:
    input: expand("test_output_{text}_{num}.txt", text=["A", "B", "C"], num=[1, 2])

rule make_output:
    input: "test_input_{text}_{num}.txt"
    output: "test_output_{text}_{num}.txt"
    shell:
        """
        md5sum {input} > {output}
        """

上記のスネークファイルを実行すると、次のエラーが発生します。

MissingInputException in line 4 of /tmp/Snakefile:
Missing input files for rule make_output:
test_input_B_1.txt

このエラーの理由は、内部で をexpand使用itertools.productしてワイルドカードの組み合わせを生成しているためです。そのうちのいくつかはたまたま不足しているファイルに対応しています。

望ましくないワイルドカードの組み合わせを除外するには?

4

1 に答える 1

10

このexpand関数は、デフォルトの関数とは異なる関数を使用してワイルドカード値を結合するために、2 番目のオプションの非キーワード引数を受け入れます。

itertools.product生成されたワイルドカードの組み合わせが事前に確立されたブラックリストに含まれていないことを確認する高次ジェネレーターでラップすることにより、フィルター処理されたバージョンを作成できます。

from itertools import product

def filter_combinator(combinator, blacklist):
    def filtered_combinator(*args, **kwargs):
        for wc_comb in combinator(*args, **kwargs):
            # Use frozenset instead of tuple
            # in order to accomodate
            # unpredictable wildcard order
            if frozenset(wc_comb) not in blacklist:
                yield wc_comb
    return filtered_combinator

# "B_1" and "C_2" are undesired
forbidden = {
    frozenset({("text", "B"), ("num", 1)}),
    frozenset({("text", "C"), ("num", 2)})}

filtered_product = filter_combinator(product, forbidden)

rule all:
    input:
        # Override default combination generator
        expand("test_output_{text}_{num}.txt", filtered_product, text=["A", "B", "C"], num=[1, 2])

rule make_output:
    input: "test_input_{text}_{num}.txt"
    output: "test_output_{text}_{num}.txt"
    shell:
        """
        md5sum {input} > {output}
        """

不足しているワイルドカードの組み合わせは、構成ファイルから読み取ることができます。

json 形式の例を次に示します。

{
    "missing" :
    [
        {
            "text" : "B",
            "num" : 1
        },
        {
            "text" : "C",
            "num" : 2
        }
    ]
}

このforbiddenセットは、snakefile で次のように読み取られます。

forbidden = {frozenset(wc_comb.items()) for wc_comb in config["missing"]}
于 2016-12-16T13:31:10.263 に答える