Snakemake 在规则中使用不同的通配符

问题描述 投票:0回答:2

我正在尝试创建 snakemake 规则,该规则接收我的 fastq 文件的输入并在输出中为每个

fastq
文件返回一个 .sam 文件。

我有这样一个文件:

FILE    TYPE    SM    LB    ID    PU          PL
xfgh.fastq.gz  Single      IND1  IND1  IND1  Platform    Illumina
IND2.fastq.gz     Single  IND2  IND2  IND2  Platform    Illumina
zfgv.fastq.gz  Single      IND3  IND3  IND3  Platform    Illumina 
IND4_P1.fastq.gz  Single      IND4  IND4  IND4  Platform    Illumina

所以我做了类似的事情。
我用熊猫打开我的数据框:

pd.read_csv("info_file.txt")
并且我将列文件 SM 和 ID 存储在列表中

我创建我的规则:

rule all:
    input:
        sam_file = expand("ALIGNEMENT/{sm}/{id}.sam", sm = info_df["SM"], id = info_df["ID"])

rule alignement:
    input:
          fastq_files = "PATH/TO/{fastq}"
    output:
          sam_file = "ALIGNEMENT/{sm}/{id}.sam"

我知道输入和输出需要具有相同的通配符,但是是否存在一种方法可以让我从 file.txt 的“FILES”列中输入,并在输出中使用这样的路径:

"ALIGNEMENT/{sm}/{id}.sam"
其中 {sm} 和 { id} 是我的 file.txt 的 SM 和 ID 列

我还想为每个文件启动一个规则。

如果有人可以帮助我谢谢你

python-3.x wildcard snakemake fastq
2个回答
1
投票

我正在尝试创建 snakemake 规则,该规则接收我的 fastq 文件的输入并在输出中为每个 fastq 文件返回一个 .sam 文件。

从上面看来,在我看来,您想将

zip
添加到规则
expand
中的
all
功能。使用 zip,您可以在输入列表中显示通配符,如果没有它,您将获得
{id}
{sm}
的所有组合。

然后要获取规则

alignment
中的输入fastq文件,您需要查询信息数据框以获取给定
id
对应的FILE。您可以使用 lambda 函数或编写专用函数作为输入来执行此操作。

这是我的看法:

import pandas as pd

info_df = pd.read_csv("info_file.txt", sep='\t') 

rule all:
    input:
        expand("ALIGNEMENT/{sm}/{id}.sam", zip, sm = info_df["SM"], id = info_df["ID"])

rule alignement:
    input:
        fastq_files=lambda wc: info_df[info_df['ID'] == wc.id]['FILE'],
    output:
        sam_file = "ALIGNEMENT/{sm}/{id}.sam"
    shell:
        r"""
        echo {input.fastq_files} > {output.sam_file}
        """

0
投票

简而言之:您不需要 Snakemake。这不是一个很好的工具选择,因为它解决了与你所拥有的相反的问题。

你描述的问题是:有一个输入文件名列表并知道过程,你想循环处理它们。只需使用纯 Python,读取文件名列表,遍历名称并使用为每个输入创建输出的命令调用 shell。使用 Python 或您选择的任何其他脚本语言。

Snakemake 是解决相反目标的强大工具。起点是您要创建的目标。下一步是定义如何创建目标的规则。最后一步是提供成为依赖树叶子的 INPUT 文件,并运行管道。

解决你的问题的一种更像蛇蝎的方法可能如下所示。首先你定义你想要得到什么(注意

zip
参数):

rule all:
    input:
        sam_file = expand("ALIGNEMENT/{sm}/{id}.sam", zip, sm=info_df["SM"], id=info_df["ID"])

然后您可以定义一个规则来创建每个 sam 文件。请注意,

{fastq}
被替换为字典,该字典提供从
(sm, id)
对到 fastq 值的映射:

rule create_sam:
    input:
        lambda wildcards: f"PATH/TO/{mapping[(wildcards.sm, wildcards.id)]}"
    output:
        sam_file = "ALIGNEMENT/{sm}/{id}.sam"

最后,您需要从 csv 文件中创建一个

mapping
字典作为全局对象。不是解决错误问题的最佳方案。

更新: 尽管@dariober 提供了解决问题的有效答案,但我坚持认为在这种情况下没有必要使用 Snakemake。当存在不必要的复杂性时,Snakemake 提供的所有好处都会丢失。作为替代解决方案,我提供了一个没有讨厌的 lambda 的简单的单一规则管道。

rule keep_it_simple_stupid:
    script:
        with open("info_file.txt") as f:
            next(f)
            for row in f:
                filename, _, sm, _, id, _, _ = row.split('\t')
                shell(f"do whatever you want with {filename}, {sm}, and {id}")

这条规则的主体是纯准系统 Python。如果它是 Snakemake 更惯用的更大管道的一部分,那么将其包装到 Snakemake 规则中可能是有意义的。但如果不是 - 应该避免将 Snakemake 作为任务的错误工具。

© www.soinside.com 2019 - 2024. All rights reserved.