Змея - не удалять вывод невыполненных правил

У меня есть рабочий процесс змейки, содержащий правило, которое запускает другой «внутренний» рабочий процесс змейки. Иногда происходит сбой определенного правила внутреннего рабочего процесса, что означает сбой внутреннего рабочего процесса. В результате все файлы, перечисленные под output внутреннего рабочего процесса, удаляются внешним рабочим процессом, даже если правила внутреннего рабочего процесса, создавшего их, выполнены успешно.
Есть ли способ предотвратить удаление змейкой выводов невыполненных правил? Или, может быть, вы можете предложить другой обходной путь?
Несколько заметок:

  • Выходные данные внутреннего рабочего процесса должны быть перечислены, поскольку они используются в качестве входных данных для других правил внешнего рабочего процесса.
  • Я попытался установить выходные данные внутреннего рабочего процесса как protected, но это не помогло.
  • Я также пытался добавить exit 0 в конец вызова внутреннего рабочего процесса, чтобы змейка считала, что он успешно завершен,

так:

rule run_inner:
    input:
        inputs...
    output:
        outputs...
    shell:
        """
        snakemake -s inner.snakefile
        exit 0
        """

но выходы все равно удаляются.
Был бы признателен за любую помощь. Спасибо!

Связанный: stackoverflow.com/questions/55419603

sappjw 04.01.2023 20:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
1 419
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Одним из обходных путей является использование 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"))

Спасибо, это интересное направление, но как мне таким образом вернуть выходные файлы к их ожидаемому пути? Они понадобятся мне для возобновления рабочего процесса.

soungalo 23.12.2020 12:19

Я не думаю, что это сработает. Если команда shell не удалась, змейка удалит файлы, перечисленные в output, и завершит работу. Он не будет продолжаться и выполнять остальную часть директивы run.

dariober 23.12.2020 14:18

@dariober, не думай, просто проверь. Это не функция shell(), которая удаляет выходные данные, а процедура очистки правила. Эта процедура не вызывается до завершения скрипта run.

Dmitry Kuzminov 23.12.2020 17:58

@DmitryKuzminov Я проверил это, я все еще не думаю, что сценарий запуска работает до конца. В каталоге запуска ставлю shell("touch {output}; exit 1"); os.rename(output[0], output[0] + '.done'). shell создает вывод и терпит неудачу, поэтому os.rename никогда не выполняется, а output[0] + '.done' не создается. Можете ли вы опубликовать воспроизводимый пример?

dariober 23.12.2020 18:19

@dariober, хм, мой первоначальный сценарий был неправильным. После включения shell в try/except это начинает работать.

Dmitry Kuzminov 23.12.2020 18:52
Ответ принят как подходящий

Один из вариантов может заключаться в том, чтобы 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 был именно тем, что мне было нужно, и на самом деле довольно прост в использовании.

soungalo 23.12.2020 17:42

Программа «сбой», когда возвращает ненулевое возвращаемое значение. Поэтому нам нужно только «исправить» эту проблему, чтобы обмануть внутреннюю оболочку, думая, что все программы успешно завершены. Самый простой способ — использовать 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 либо в командной строке, либо через профиль. Это предотвратит удаление незавершенных выходных файлов неудачными заданиями.

Другие вопросы по теме