execução condicional de regras snakemake com base na coluna da metatabela

Jan 15 2021

Estou tentando usar uma coluna em um arquivo de texto para executar regras condicionalmente em um fluxo de trabalho snakemake.

O arquivo de texto é o seguinte:

id  end sample_name fq1 fq2
a   paired  test_paired resources/SRR1945436_1.fastq.gz resources/SRR1945436_2.fastq.gz
b   single  test_single resources/SRR1945436.fastq.gz   NA

Para cada amostra no arquivo de texto, se o valor na coluna final for pareado, gostaria de usar a regra cp_fastq_pe e se end for único, gostaria de usar a regra cp_fastq_pe para processar os arquivos fq1 e fq2 ou apenas fq1, respectivamente.

parte relevante do Snakefile é a seguinte:

import pandas as pd
samples = pd.read_table("config/samples.tsv").set_index("id", drop=False)
all_ids=list(samples["id"])

rule cp_fastq_pe:
    """
    copy file to resources
    """
    input:
        fq1=lambda wildcards: samples.loc[wildcards.id, "fq1"],
        fq2=lambda wildcards: samples.loc[wildcards.id, "fq2"]
    output:
        "resources/fq/{id}_1.fq.gz",
        "resources/fq/{id}_2.fq.gz"
    shell:
        """
        cp {input.fq1} {output[0]}
        cp {input.fq2} {output[1]}
        """

rule cp_fastq_se:
    """
    copy file to resources
    """
    input:
        fq1=lambda wildcards: samples.loc[wildcards.id, "fq1"]
    output:
        "resources/fq/{id}.fq.gz",
    shell:
        """
        cp {input.fq1} {output}
        """

É possível fazer isso?

Respostas

2 DmitryKuzminov Jan 15 2021 at 14:54

Eu tive um problema semelhante, que resolvi aqui: Como tornar a entrada Snakemake opcional, mas não vazia?

Aqui está a ideia ajustada ao seu problema. Primeiro, você precisa especificar o ruleorderpara resolver a ambiguidade (caso contrário, o único sempre pode ser aplicado sempre que o emparelhado for possível):

ruleorder: cp_fastq_pe > cp_fastq_se

Em seguida, em sua cp_fastq_peregra, você precisa definir uma função que retorna um arquivo válido (para o caso pareado) ou retorna um marcador de posição para um arquivo não existente:

rule cp_fastq_pe:
    input:
        fq1=lambda wildcards: samples.loc[wildcards.id, "fq1"],
        fq2=lambda wildcards: samples.loc[wildcards.id, "fq2"] if "fq2" in samples else "non-existing-filename"

Esta regra seria aplicada a todas as amostras onde quer que o "fq2"campo exista e represente um arquivo válido. A outra regra seria selecionada para o resto das amostras.