exécution conditionnelle de règles de snakemake basées sur la colonne dans métatable

Jan 15 2021

J'essaie d'utiliser une colonne dans un fichier texte pour exécuter conditionnellement des règles dans un flux de travail snakemake.

Le fichier texte est le suivant:

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

Pour chaque échantillon du fichier texte, si la valeur de la colonne de fin est appariée, je voudrais utiliser la règle cp_fastq_pe et si la fin est unique, je voudrais utiliser la règle cp_fastq_pe pour traiter respectivement les fichiers fq1 et fq2 ou simplement fq1.

La partie pertinente de Snakefile est la suivante:

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}
        """

Est-il possible de faire cela?

Réponses

2 DmitryKuzminov Jan 15 2021 at 14:54

J'ai eu un problème similaire, que j'ai résolu ici: Comment rendre l'entrée Snakemake facultative mais pas vide?

Voici l'idée adaptée à votre problème. Tout d'abord, vous devez spécifier le ruleorderpour résoudre l'ambiguïté (sinon le single pourrait toujours être appliqué chaque fois que l'appariement est possible):

ruleorder: cp_fastq_pe > cp_fastq_se

Ensuite, dans votre cp_fastq_perègle, vous devez définir une fonction qui renvoie un fichier valide (pour le cas apparié) ou renvoie un espace réservé pour le fichier non existant:

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"

Cette règle serait appliquée à tous les échantillons partout où le "fq2"champ existe et représente un fichier valide. L'autre règle serait sélectionnée pour le reste des échantillons.