Строковое форматирование подстановочных знаков в выходных строках - PullRequest
4 голосов
/ 11 июля 2020

Я относительно новичок в snakemake, и у меня возникли некоторые проблемы с адаптацией рабочего процесса DeepVariant с разбросом и сборкой к правилам snakemake. DeepVariant использует формат *.00001-of-00256.* для отслеживания номера сегмента в промежуточном формате файла, поэтому мне нужно использовать форматирование строки, чтобы указать как номер сегмента, так и общее количество сегментов в пределах input, output и shell. поля, и я указываю номер шарда как подстановочный знак в params правила scatter. Функция expand() в поле input правила gather правильно генерирует ожидаемые имена файлов, но не может найти пути к входным файлам, которые были бы сгенерированы на шаге scatter.

Я создал минимально воспроизводимый пример ниже, а также результат выполнения этого примера (слегка отредактирован, чтобы удалить некоторую информацию о пути).

N_SHARDS = 8

rule all:
    input: "done.txt"


rule scatter:
    input: "start.txt"
    output: f"test_{{shard:05}}-of-{N_SHARDS:05}.txt"
    params:
        shard = range(N_SHARDS)
    message: "scattering"
    shell:
        f"echo {{wildcards.shard}} {N_SHARDS} > {{output}}"


rule gather:
    input: expand(f"test_{{shard:05}}-of-{N_SHARDS:05}.txt", shard=range(N_SHARDS))
    output: touch("done.txt")
    shell: "echo gathering"
$ touch start.txt
$ snakemake -s example.smk -j 1
Building DAG of jobs...
MissingInputException in line 17 of /redacted/example.smk:
Missing input files for rule gather:
test_00002-of-00008.txt
test_00000-of-00008.txt
test_00006-of-00008.txt
test_00001-of-00008.txt
test_00004-of-00008.txt
test_00005-of-00008.txt
test_00007-of-00008.txt
test_00003-of-00008.txt

Я построил очень похожие правила для другого разброса -собрать концепции, которые не требуют строкового форматирования подстановочных знаков, так что это единственное, о чем я могу думать, что отличается в данном случае. Я был бы признателен за любую информацию!

ОБНОВЛЕНИЕ : полезный пользователь твиттера отметил , что я могу удалить :05 в scatter -> output и правило работает. Это замечательно, и это решает мою исходную проблему, но только потому, что DeepVariant терпимо относится к нулевому заполнению для параметра шарда, передаваемого в командной строке. Есть ли решение, позволяющее применить форматирование к подстановочному знаку?

1 Ответ

2 голосов
/ 14 июля 2020

Вот как я бы это сделал:

N_SHARDS = '00008'

shard = ['%05d' % x for x in range(int(N_SHARDS))]

wildcard_constraints:
    shard= '|'.join([re.escape(x) for x in shard])

rule all:
    input: 
        "done.txt",

rule scatter:
    input: 
        "start.txt",
    output:
        "test_{shard}-of-%s.txt" % N_SHARDS,
    shell:
        r"""
        echo {wildcards.shard} %s > {output}"
        """ % N_SHARDS
    
rule gather:
    input:
        expand('test_{shard}-of-%s.txt' % N_SHARDS, shard= shard),
    output: 
        touch("done.txt")
    shell: 
        "echo gathering"

Бит wildcard_constraints может быть избыточным, но я обычно использую его довольно широко, если я точно знаю, какие значения будут принимать подстановочные знаки.

Одно: кажется, вы заранее знаете, сколько шардов DeepVariant собирается сгенерировать (N_SHARDS = 8 в примере). Так ли это на самом деле? Если нет, я думаю, вам нужно прибегнуть к функциональности контрольной точки snakemake.

...