Для задачи мне нужно реализовать логику как в скрипте ниже. (Исходник сценария ). Но в текущей версии флаг «каталог» действителен только для выходов, а не для входов.
Как это можно сделать в текущей версии?
OUTDIR = "first_directory"
SNDDIR = "second_directory"
THRDIR = "third_directory"
def combine(wildcards):
# read the first set of outputs
ck_output = checkpoints.make_some_files.get(**wildcards).output[0]
FIRSTS, = glob_wildcards(os.path.join(ck_output, "{sample}.txt"))
# read the second set of outputs
sn_output = checkpoints.make_more_files.get(**wildcards).output[0]
SECONDS, = glob_wildcards(os.path.join(sn_output, "{smpl}.txt"))
return expand(os.path.join(THRDIR, "{first}.{second}.tsv"), first=FIRSTS, second=SECONDS)
rule all:
input:
combine
checkpoint make_some_files:
output:
directory(OUTDIR)
shell:
"""
mkdir {output};
N=$(((RANDOM%5)+1));
for D in $(seq $N); do
touch {output}/$RANDOM.txt
done
"""
checkpoint make_more_files:
output:
directory(SNDDIR)
shell:
"""
mkdir {output};
N=$(((RANDOM%5)+1));
for D in $(seq $N); do
touch {output}/$RANDOM.txt
done
"""
rule make_third_files:
input:
directory(OUTDIR),
directory(SNDDIR),
output:
os.path.join(THRDIR, "{first}.{second}.tsv")
shell:
"""
touch {output}
"""
Дополнение к вопросу, посвященному обсуждению использования подстановочных знаков.
Изменение двух правил из источника, предоставленного ссылкой в конвейере, с помощью глобальной переменной SMP.
rule all:
input:
get_second_files,
expand("list_of_files_{SAMPLE}.txt",SAMPLE=SMP)
rule list_all_files:
input:
expand(os.path.join(SNDDIR, "{SAMPLE}.tsv"), SAMPLE=SMP)
output:
out = "list_of_files_{SAMPLE}.txt"
shell:
"""
echo {input} > {output.out}
"""
Вы по-прежнему можете использовать пути к каталогам в директиве input
, но не со специальным флагом directory()
, предназначенным для обозначения того, что его можно удалить в начале выполнения, и чтобы не обнаруживать изменения в отображении каталога, поскольку изменения требуют повторного использования. -выполнение правил, как описано в документации здесь.
Это модифицированная версия, которая работала у меня со Snakemake версии 8.18.1.
OUTDIR = "first_directory"
SNDDIR = "second_directory"
THRDIR = "third_directory"
def combine(wildcards):
# read the first set of outputs
ck_output = checkpoints.make_some_files.get(**wildcards).output[0]
FIRSTS, = glob_wildcards(os.path.join(ck_output, "{sample}.txt"))
# read the second set of outputs
sn_output = checkpoints.make_more_files.get(**wildcards).output[0]
SECONDS, = glob_wildcards(os.path.join(sn_output, "{smpl}.txt"))
return expand(os.path.join(THRDIR, "{first}.{second}.tsv"), first=FIRSTS, second=SECONDS)
rule all:
input:
OUTDIR,
SNDDIR,
combine
checkpoint make_some_files:
output:
directory(OUTDIR)
shell:
"""
mkdir {output};
N=$(((RANDOM%5)+1));
for D in $(seq $N); do
touch {output}/$RANDOM.txt
done
"""
checkpoint make_more_files:
output:
directory(SNDDIR)
shell:
"""
mkdir {output};
N=$(((RANDOM%5)+1));
for D in $(seq $N); do
touch {output}/$RANDOM.txt
done
"""
rule make_third_files:
input:
OUTDIR,
SNDDIR,
output:
os.path.join(THRDIR, "{first}.{second}.tsv")
shell:
"""
touch {output}
Другое изменение заключается в том, что я добавил первые два выходных каталога в input
главного правила.
Вы можете увидеть настройку для работы в сеансе Jupyter и результат здесь.
Вы даже можете легко запустить его самостоятельно, не касаясь своей системы, во временном сеансе Jupyter, обслуживаемом MyBinder.org, если вы зайдете туда и следуйте инструкциям вверху, чтобы запустить сеанс, а затем загрузите в него этот блокнот и запустите все клетки.
«Возможно, вы знаете, есть ли способ использовать подстановочные знаки из функции для всех правил в конвейере?» Полагаю, вы пытаетесь понять, для чего нужны input functions
? См. здесь и здесь . (Или прямой Python, см. здесь или здесь или здесь.) Может быть? Трудно сказать по...
Фрагмент <продолжение>, который вы добавили в конец исходного сообщения. Вы можете использовать сайт обмена кодом или Gist, чтобы поделиться большей частью кода. Если это невозможно, то, возможно, это само заслуживает поста? Потому что я не понимаю, как это правило list_all_files
вписывается в то, что мы обсуждали.
Загрузил код сюда. Не могу понять, почему не сохранилось обновленное значение глобальной переменной SMP? Вместо файлов: list_of_files_7537.txt,list_of_files_30172.txt... у меня получился list_of_files_None.txt
Мне пришлось бы поискать больше, но вы установили для SMP значение None в Python, а затем в правиле по умолчанию вы установили для SAMPLE значение SMP, что равно None. Итак, вы установили его. Затем, как только вы зафиксируете это там, Snakemake распространит его. Не знаю, что вы надеялись там сделать прямо сейчас, но я посмотрю позже.
Еще раз спасибо за совет и предоставленный источник! Я решил свою проблему. Код доступен здесь.
Какой из них это исправил? «2-е» или «3-е издание»? Чтобы помочь вам в будущем и, возможно, другим, вы можете написать немного о том, что решение было, или поместить его в блокнот, на который вы ссылаетесь, в уценке.
Добавлю комментарии в блокнот
Это хороший пример сочетания использования контрольных точек внутри функции ввода, когда вы с самого начала не знаете конкретные файлы. Плюс он работает с самой последней версией Snakemake!
Большое спасибо за подробный ответ! Возможно, вы знаете, есть ли способ использовать подстановочные знаки из функции для всех правил в конвейере? Я использовал код из приведенного выше источника с переменной SMP=None и внес изменения в правила all и list_all_files. Я добавил модификации в вопрос, к сожалению, не смог опубликовать весь код из-за ограничений на количество кода в вопросе. Текущая версия правила list_all_files использует значение SMP=None. Как вместо этого использовать измененную переменную SMP? Очень ценю вашу помощь!