У меня есть рабочий процесс змейки, содержащий правило, которое запускает другой «внутренний» рабочий процесс змейки.
Иногда происходит сбой определенного правила внутреннего рабочего процесса, что означает сбой внутреннего рабочего процесса. В результате все файлы, перечисленные под output
внутреннего рабочего процесса, удаляются внешним рабочим процессом, даже если правила внутреннего рабочего процесса, создавшего их, выполнены успешно.
Есть ли способ предотвратить удаление змейкой выводов невыполненных правил? Или, может быть, вы можете предложить другой обходной путь?
Несколько заметок:
protected
, но это не помогло.exit 0
в конец вызова внутреннего рабочего процесса, чтобы змейка считала, что он успешно завершен,так:
rule run_inner:
input:
inputs...
output:
outputs...
shell:
"""
snakemake -s inner.snakefile
exit 0
"""
но выходы все равно удаляются.
Был бы признателен за любую помощь. Спасибо!
Одним из обходных путей является использование run
вместо shell
:
rule run_inner:
input:
inputs...
output:
outputs...
run:
shell("""snakemake -s inner.snakefile""")
# Add your code here to store the files before removing
Даже если сценарий в вызове функции shell
не работает, файлы все еще существуют до тех пор, пока сценарий в разделе run
не завершится. Вы можете скопировать файлы туда в безопасное место.
Обновление: вам нужно обрабатывать исключения, чтобы продолжать выполнение всякий раз, когда скрипт возвращает ошибку. Сценарий ниже иллюстрирует идею: функция print
из блока except:
печатает True
, другая из onerror
печатает False
rule run_inner:
output:
"output.txt"
run:
try:
shell("""touch output.txt; exit 1""")
except:
print(os.path.exists("output.txt"))
onerror:
print(os.path.exists("output.txt"))
Спасибо, это интересное направление, но как мне таким образом вернуть выходные файлы к их ожидаемому пути? Они понадобятся мне для возобновления рабочего процесса.
Я не думаю, что это сработает. Если команда shell
не удалась, змейка удалит файлы, перечисленные в output
, и завершит работу. Он не будет продолжаться и выполнять остальную часть директивы run
.
@dariober, не думай, просто проверь. Это не функция shell()
, которая удаляет выходные данные, а процедура очистки правила. Эта процедура не вызывается до завершения скрипта run
.
@DmitryKuzminov Я проверил это, я все еще не думаю, что сценарий запуска работает до конца. В каталоге запуска ставлю shell("touch {output}; exit 1"); os.rename(output[0], output[0] + '.done')
. shell
создает вывод и терпит неудачу, поэтому os.rename
никогда не выполняется, а output[0] + '.done'
не создается. Можете ли вы опубликовать воспроизводимый пример?
@dariober, хм, мой первоначальный сценарий был неправильным. После включения shell
в try/except это начинает работать.
Один из вариантов может заключаться в том, чтобы run_inner
создать фиктивный выходной файл, который отмечает выполнение правила. Правила, следующие за run_inner
, будут принимать на вход фиктивный файл. Например:
rule run_inner:
...
output:
# or just 'run_inner.done' if wildcards are not involved
touch('{sample}.run_inner.done'),
shell:
'snakemake -s inner.snakefile'
run next:
input:
'{sample}.run_inner.done',
params:
real_input= '{sample}.data.txt', # This is what run_inner actually produces
shell:
'do stuff {params.real_input}'
Если snakemake -s inner.snakefile
не удается, фиктивный вывод будет удален, но snakemake -s inner.snakefile
перезапустится с того места, где он был.
Другим вариантом может быть интеграция правил в inner.snakefile
во внешний конвейер, например. включает заявление. Я считаю, что этот вариант предпочтительнее, но, конечно, его будет сложнее реализовать.
Спасибо! include
был именно тем, что мне было нужно, и на самом деле довольно прост в использовании.
Программа «сбой», когда возвращает ненулевое возвращаемое значение. Поэтому нам нужно только «исправить» эту проблему, чтобы обмануть внутреннюю оболочку, думая, что все программы успешно завершены. Самый простой способ — использовать some error command || true
. Ниже приведен минимальный пример:
rule test:
output:
"test.output",
shell:
"""
touch test.output
# below cat will trigger error
cat file_not_exist || true
"""
Вы обнаружите, что, несмотря на ошибку, выданную cat
, test.output
все еще выживает.
Вы можете использовать опцию --keep-incomplete для snakemake
либо в командной строке, либо через профиль. Это предотвратит удаление незавершенных выходных файлов неудачными заданиями.
Связанный: stackoverflow.com/questions/55419603