Можно ли добавить условный оператор в правило snakemake all?

#python #snakemake #qiime

#python #snakemake #qiime

Вопрос:

Я хочу запустить несколько snakefiles с именем qc.smk , dada2.smk , picrust2.smk используя singularity . Тогда есть один snakefile longitudinal.smk , который я хотел бы запустить условно. Например, если используются продольные данные.

 # set vars

LONGITUDINAL = config['perform_longitudinal']

rule all:
  input:
    # fastqc output before trimming
    raw_html = expand("{scratch}/fastqc/{sample}_{num}_fastqc.html", scratch = SCRATCH, sample=SAMPLE_SET, num=SET_NUMS),
    raw_zip = expand("{scratch}/fastqc/{sample}_{num}_fastqc.zip", scratch = SCRATCH, sample=SAMPLE_SET, num=SET_NUMS),
    raw_multi_html = SCRATCH   "/fastqc/raw_multiqc.html",
    raw_multi_stats = SCRATCH   "/fastqc/raw_multiqc_general_stats.txt"

# there are many more files in rule all

##### setup singularity #####

singularity: "docker://continuumio/miniconda3"

##### load rules #####

include: "rules/qc.smk"
include: "rules/dada2.smk"
include: "rules/phylogeny.smk"
include: "rules/picrust2.smk"

if LONGITUDINAL == 'yes':
    include: 'rules/longitudinal.smk'
    print("Will perform a longitudinal analysis")
else:
    print("no longitudinal analysis")
 

Приведенный выше код работает, только если я использую продольный набор данных. Однако, когда я не выполняю продольный анализ, snakemake завершается с ошибкой и говорит что-то вроде:

 MissingInputException in line 70 of /mnt/c/Users/noahs/projects/tagseq-qiime2-snakemake-1/Snakefile:
Missing input files for rule all:
 

Я думаю, что если бы я смог добавить аналогичный условный оператор, подобный тому, который у меня есть для моего внешнего snakefile, snakemake не волновался бы из-за того, что я не включил продольный snakefile.

Ответ №1:

Вы можете определить список (или dict) того, что вы хотите получить в качестве выходных данных за пределами rule all , и передать это на вход, работает что-то вроде этого:

 myoutput = list()

if condition_1 == True:
    myoutput.append("file_1.txt")
if condition_2 == True:
    myoutput.append("file_2.txt")

rule all:
    input:
        myoutput
 

Редактировать:

Либо поместить myoutput в качестве первого во входных данных правила all:

 rule all:
    input:
        myoutput,
        raw_html = "raw_html_path",
        raw_zip = "raw_zip_path"
 

или сделайте его именованным и разместите его где угодно:

 rule all:
    input:
        raw_html = "raw_html_path",
        myoutput = myoutput,
        raw_zip = "raw_zip_path"
 

В Python (и snakemake) именованные позиционные аргументы всегда идут перед именованными аргументами.

Комментарии:

1. Спасибо вам за ответ. Я не уверен, совершаю ли я ошибку со своей стороны, потому что эта структура не работает для меня. Должны ли все мои выходные данные быть добавленными списками, чтобы это работало? В настоящее время все мои выходные файлы обычно перечислены в моем правиле all и добавлены myoutput под остальными моими входными файлами, и я получил эту ошибку: SyntaxError in line 178 of /mnt/c/Users/noahs/projects/tagseq-qiime2-snakemake-1/Snakefile: positional argument follows keyword argument 178 — это строка в правиле all, куда я добавил myoutput

2. переместите myoutput список, чтобы он был первым в all: input: , или сделайте что-нибудь подобное all: input: optional = myoutput .

3. Пингую вас так @Noah_Seagull , так как я не уверен, что вы получите уведомление о моем ответе в противном случае

4. Это все еще не работает для меня. Возможно, функции append не нравится, как называются мои файлы, хотя моя схема именования отлично работает в snakemake. Вот пример имен файлов, которые я пытаюсь передать через функцию добавления, как вы предложили. myout.append("pw_diff = OUTPUTDIR '/qiime2/asv/longitudinal/' PROJ ANALYSIS 'pairwise-differences.qzv'")

5. Большое вам спасибо! вы спасатель. Я смог заставить его работать, сначала определив позиционные аргументы вне правила all . Поскольку мне нужно было добавить один список из нескольких входных данных в другой список входных данных, мне также пришлось использовать extend вместо append . Но я бы не смог разобраться в этом с вашей помощью.

Ответ №2:

Решение для объединения оператора расширения формы списка:

Я использовал конфигурационный файл для передачи инструкций в Snakefile

 ## Config.yml ##
# longitudinal analysis
perform_longitudinal: 'yes' # yes for longitudinal analysis 
 

Когда в конфигурации будет введено «да», Snakemake включит дополнительные переменные в правило all и запустит дополнительный Snakefile для генерации этих файлов. В итоге оказалось несколько Snakefiles, поэтому я использовал singularity, чтобы сообщить Snakemake, что правило all входные файлы были для всех 6 Snakefiles.

 ## Snakefile ##

configfile: "config.yaml"

LONGITUDINAL = config['perform_longitudinal']

 # rule all input files
 raw_html=file.txt, 
 raw_zip=file.txt,
 raw_multi_htmt=file.txt,
 raw_multi_stats=file.txt,
 Longitudinal_analaysis_files=file.txt

# rule all files excluding longitudinal analysis
rule_all_input_list=['raw_html','raw_zip','raw_multi_htmt','raw_multi_stats']

#longitudinal analysis files
rule_all_longitudinal_input=['Longitudinal_analaysis_files']

if LONGITUDINAL == 'yes':

    rule_all_input_list.extend(rule_all_longitudinal_input)

# conditionally add Snakefile to workflow
    include: 'rules/longitudinal.smk'

    print("Will perform a longitudinal analysis")

else:
    print("no longitudinal analysis")


rule all:
    input:
        data = rule_all_input_list

##### setup singularity #####

# this container defines the underlying OS for each job when using the workflow
# with --use-conda --use-singularity
singularity: "docker://continuumio/miniconda3"

##### load rules #####

include: "rules/qc.smk"
include: "rules/dada2.smk"
include: "rules/phylogeny.smk"
include: "rules/picrust2.smk"
include: "rules/differential.smk"
 

У меня есть менее упрощенная версия того, как я заставил это работать на GitHub https://github.com/nasiegel88/tagseq-qiime2-snakemake-1