Может ли SnakeMake быть принудительно перезапущен при отсутствии файлов?
Когда файл, созданный ранее в конвейере, удаляется, SnakeMake, похоже, не считает, что это проблема, если существуют более поздние файлы:
rule All:
input: "testC1.txt", "testC2.txt"
rule A:
input: "{X}{Y}.txt"
output: "{X}A{Y}.txt"
shell: "cp {input} {output}"
rule B:
input: "{X}A{Y}.txt"
output: "{X}B{Y}.txt"
shell: "cp {input} {output}"
rule C:
input: "{X}B{Y}.txt"
output: "{X}C{Y}.txt"
shell: "cp {input} {output}"
Сохраните этот SnakeFile в test.sf и сделайте это:
rm testA*.txt testB*.txt testC*.txt
echo "test1" >test1.txt
echo "test2" >test2.txt
snakemake -s test.sf
# Rerun:
snakemake -s test.sf
# SnakeMake says all is up to date, which it is.
# Remove intermediate results:
rm testA1.txt
# Rerun:
snakemake -s test.sf
SnakeMake говорит, что все в курсе. Он не обнаруживает отсутствующий testA1.txt.
Кажется, я что-то вспомнил в онлайн-руководстве по SnakeMake об этом, но больше не могу его найти.
Я предполагаю, что это ожидаемое поведение SnakeMake. Иногда это может быть желательным поведением, но иногда вы можете захотеть, чтобы он обнаружил и восстановил отсутствующий файл. Как это может быть сделано?
2 ответа
Как уже упоминалось в этом другом ответе, -R
Параметр может помочь, но есть еще варианты:
Принудительно восстановить весь рабочий процесс
Когда вы звоните
snakemake -F
это вызовет перестройку всего конвейера. В основном это означает, что нужно забыть все промежуточные файлы и начать заново. Это определенно (повторно) сгенерирует все промежуточные файлы в пути. Недостатком является то, что это может занять некоторое время.
Принудительно определенное правило
Это царство -R <rule>
параметр. Это повторно запускает данное правило и все правила, которые зависят от него. Так что в вашем случае
snakemake -R A -s test.sf
перезапустил бы правило А (чтобы построить testA1.txt
от test.txt
) и правила B, C и All, поскольку они зависят от A. Имейте в виду, что при этом запускаются все требуемые копии правила A, так что в вашем примере testA2.txt
и все, что из этого следует, также перестраивается.
Если в вашем примере вы бы удалили testB1.txt
вместо этого только правила B
а также C
был бы перезапущен.
Почему это происходит?
Если я правильно помню, snakemake определяет, нужно ли перестраивать файл по его времени. Так что если у вас есть версия testA1.txt
это моложе (как в более недавно созданном), чем testB1.txt
, testB1.txt
должен быть восстановлен с помощью rule B
, чтобы убедиться, что все в курсе. Следовательно, вы не можете легко восстановить только testA1.txt
без создания также всех следующих файлов, если только вы не измените время их работы.
Я не пробовал это, но это можно сделать с помощью змей --touch
параметр. Если вам удастся запустить только правило A
а потом беги snakemake -R B -t
, который касается всех выходных файлов правил B
и после этого вы могли бы получить действительное состояние рабочего процесса, фактически не повторяя все промежуточные шаги.
Я нашел эту тему некоторое время назад о --forcerun
/-R
параметр, который может быть информативным.
В конечном счете, snakemake принудительно выполнит весь конвейер, если вы захотите восстановить этот промежуточный файл, не имея отдельного правила для него или не включив его в качестве цели.
Действительно, было бы неплохо, если бы snakemake имел флаг, который искал недостающие промежуточные результаты и регенерировал их, если они отсутствовали (все его зависимости). Я не знаю о таком варианте, но есть обходные пути. Обратите внимание-R
вариант, предложенный m00am, и Джон Чанг регенерирует все остальные файлы, независимо от того, отсутствуют ли промежуточные файлы. Так что это совсем не идеально.
Обходной путь 1: принудительное воссоздание файла
Принудительное воссоздание промежуточного файла с помощью -R
или -f
флаг (справка скопирована ниже). Ключевым моментом здесь является явная ориентация на файл, а не на правило.
snakemake -s test.sf testA1.txt # only works if testA1.txt was deleted
# or
snakemake -s test.sf -R testA1.txt # testA1.txt can be present or absent
# or
snakemake -s test.sf -f testA1.txt
# or
snakemake -s test.sf -F testA1.txt
Обратите внимание, что позже для последних двух конвейер необходимо запустить снова, чтобы обновить зависимости:
snakemake -s test.sf
предотвращать обновление зависимых файлов (касаясь файлов)
Если вы не хотите, чтобы зависимые файлы (например, testB1.txt, testC1.txt) обновлялись, есть также варианты.
Вы можете регенерировать testA1.txt, а затем "сбросить" время его модификации, например, в исходный файл, что не позволит конвейеру что-либо обновить:
snakemake -s test.sf -f testA1.txt
touch testA1.txt -r test1.txt
snakemake -s test.sf
теперь не к чему, так как testB1.txt
новее чем testA1.txt
Или вы можете пометить зависимые файлы (например, testB1.txt, testC1.txt) как "более новые", используя --touch
:
snakemake -s test.sf -f testA1.txt
snakemake -s test.sf --touch
Обходной путь 2: создание нового правила
Змеиный файл можно расширить новым правилом:
rule A_all:
input: "testA1.txt", "testA2.txt"
Что тогда можно было бы назвать так:
snakemake A_all -s test.sf
Это только сгенерирует testA1.txt
, похожий на -f
в описанном выше рабочем процессе, поэтому необходимо повторно запустить трубопровод или изменить время модификации.
Уловка может "обновить" промежуточный файл с помощью --touch
snakemake -s test.sf --touch testA1.txt -n
Это будет "обновлять" testA1.txt
. Для воссоздания зависимых файлов необходимо запустить snakemake как обычно:
snakemake -s test.sf
Обратите внимание: это не сработает, если testA1.txt
был удален, это нужно сделать вместо удаления.
Соответствующая справка по используемым параметрам:
--touch, -t Touch output files (mark them up to date without
really changing them) instead of running their
commands. This is used to pretend that the rules were
executed, in order to fool future invocations of
snakemake. Fails if a file does not yet exist.
--force, -f Force the execution of the selected target or the
first rule regardless of already created output.
--forceall, -F Force the execution of the selected (or the first)
rule and all rules it is dependent on regardless of
already created output.
--forcerun [TARGET [TARGET ...]], -R [TARGET [TARGET ...]]
Force the re-execution or creation of the given rules
or files. Use this option if you changed a rule and
want to have all its output in your workflow updated.