snakemake: Как использовать glob_wildcards для вновь созданных файлов? - PullRequest
1 голос
/ 13 июля 2020

Проблема:

У меня есть большой рабочий процесс, который в какой-то момент создает произвольное количество файлов на {sample} с именами, например, test1.txt, test2.txt и т.д. c.

Затем мне нужно использовать эти файлы для дальнейшей обработки. Тогда входными файлами для следующего правила будут {sample}/test1.txt, {sample}/test2.txt, et c. Таким образом, test1, test2, et c становятся подстановочными знаками.

Структура данных:

---data
 ---sample1
   ---test1.txt
   ---test2.txt
   ---test3.txt
 ---sample2
   ---test1.txt
   ---test2.txt
Snakefile

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

Интуитивно я бы сделал что-то вроде этого:

samples = ['sample1', 'sample2']

rule append_hello:
  input:
    glob_wildcards('data/{sample}/{id}.txt')
  output:
    'data/{sample}/{id}_2.txt'
  shell:
    " echo {input} 'hello' >> {output} "

У меня два вопроса :

  1. Как решить эту проблему в Snakemkae?
  2. Как бы вы построили rule all, чтобы запустить это.

Любые входные данные или любые подсказки для дальнейшего чтения будут оценены.

Edit

Я думаю, что это связано с ограничениями подстановочных знаков. Когда я запускаю:

assemblies = []
for filename in glob_wildcards(os.path.join("data/{sample}", "{i}.txt")):
    assemblies.append(filename)
print(assemblies)

, я получаю два списка, в которых соответствует соответствующий индекс:

[['sample1', 'sample1', 'sample1', 'sample2', 'sample2'], ['test1', 'test2', 'test3', 'test5', 'test4']]

Теперь мне в основном нужно только указать snakemake использовать соответствующие значения подстановочных знаков.

1 Ответ

1 голос
/ 14 июля 2020

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

Вам нужна контрольная точка . Эта функция позволяет остановить Snakemake в какой-то момент и повторно оценить DAG.

samples = ["sample1", "sample2"]

rule all:
    input:
        expand("data/{sample}/processed.txt", sample=samples)


checkpoint generate_arbitrary:
    output:
        directory("data/{sample}/arbitrary")
    run:
        if wildcards.sample == "sample1":
            n = 3
        else:
            n = 2

        shell("mkdir {output}")
        for id in range(1, n + 1):
            shell(f"echo '{{id}}' > data/{wildcards.sample}/arbitrary/{id}.txt")



def aggregate_input(wildcards):
    checkpoints.generate_arbitrary.get(sample=wildcards.sample)
    ids = glob_wildcards(f"data/{wildcards.sample}/arbitrary/{{id}}.txt").id
    return expand(f"data/{wildcards.sample}/arbitrary/{{id}}.txt", id=ids)


rule append_hello:
    input:
        aggregate_input
    output:
        "data/{sample}/processed.txt"
    shell:
        "echo {input} 'hello' > {output}"
...