这更像是关于snakemake功能的技术问题。我想知道是否可以在snakemake运行期间动态改变输入样本集。
我想这样做的原因如下:让我们假设一组样本关联的bam文件。第一个规则确定每个样本的质量(基于bam文件),即所有输入文件。 但是,根据指定的标准,只有一部分样本被认为是有效的,应该进一步处理。因此,只应对已批准的bam文件执行下一步(例如基因计数或其他内容),如下面的最小示例所示:
configfile: "config.yaml"
rule all:
input: "results/gene_count.tsv"
rule a:
input: expand( "data/{sample}.bam", sample=config['samples'])
output: "results/list_of_qual_approved_samples.out"
shell: '''command'''
rule b:
input: expand( "data/{sample}.bam", sample=config['valid_samples'])
output: "results/gene_count.tsv"
shell: '''command'''
在此示例中,规则a将使用有效样本名称列表扩展配置文件,即使我相信知道这是不可能的。
当然,直接的解决方案是拥有两个不同的输入:1。)所有bam文件和2.)列出所有有效文件的文件。这将归结为在规则代码中进行样本选择。
rule alternative_b:
input:
expand( "data/{sample}.bam", sample=config['samples']),
"results/list_of_qual_approved_samples.out"
output: "results/gene_count.tsv"
shell: '''command'''
但是,您是否看到了设置规则的方法,以便可以实现第一个示例的行为?
非常感谢, 拉尔夫
答案 0 :(得分:1)
我想我的回答可能很有趣。
起初我以为不可能这样做。因为Snakemake needs the final files
在最后。因此,您不能在不知道开头的分离的情况下分离一组文件。
但后来我尝试使用动态功能。使用动态功能,您无需知道规则将创建的文件数量。
所以我编码了这个:
rule all:
input: "results/gene_count.tsv"
rule a:
input: expand( "data/{sample}.bam", sample=config['samples'])
output: dynamic("data2/{foo}.bam")
shell:
'./bloup.sh "{input}"'
rule b:
input: dynamic("data2/{foo}.bam")
output: touch("results/gene_count.tsv")
shell: '''command'''
与第一个示例一样,snakefile希望生成一个名为results/gene_count.ts
的文件。
rule a
从配置文件中获取所有样本。此规则执行选择要创建的文件的脚本。我有4 initial
个文件(geneA,geneB,geneC,geneD)和only touches two
作为第二个库中的输出(geneA和geneD文件)。 动态功能没有问题。
rule b
获取rule a
创建的所有动态文件。所以你只需要产生 results / gene_count.tsv 。我只是在示例中触及它。
以下是log of Snakemake
以获取更多信息:
Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
count jobs
1 a
1 all
1 b
3
rule a:
input: data/geneA.bam, data/geneB.bam, data/geneC.bam, data/geneD.bam
output: data2/{*}.bam (dynamic)
Subsequent jobs will be added dynamically depending on the output of this rule
./bloup.sh "data/geneA.bam data/geneB.bam data/geneC.bam data/geneD.bam"
Dynamically updating jobs
Updating job b.
1 of 3 steps (33%) done
rule b:
input: data2/geneD.bam, data2/geneA.bam
output: results/gene_count.tsv
command
Touching output file results/gene_count.tsv.
2 of 3 steps (67%) done
localrule all:
input: results/gene_count.tsv
3 of 3 steps (100%) done
答案 1 :(得分:1)
另一种不使用“动态”的方法。
并不是您不知道要使用多少文件,而是仅使用您将要开始使用的文件的子集。由于您可以生成所有潜在文件的“samples.txt”列表,因此我假设您有一个坚定的起点。
我做了类似的事情,我有初始文件,我想处理有效性,(在我的情况下,我正在提高质量〜排序,索引等)。然后我想忽略除了生成的文件之外的所有内容。
为避免创建示例文件的辅助列表,我建议创建第二个数据目录(reBamDIR),data2(BamDIR)。在data2中,您对所有有效的文件进行符号链接。这样,Snake就可以在data2目录中处理所有内容。使管道更容易向下移动,管道可以停止依赖样本列表,它可以使用通配符处理所有内容(更容易编码)。这是可能的,因为我符号链接然后标准化名称。我列出了输出规则中的符号链接文件,因此Snakemake了解它们,然后它可以创建DAG。
`-- output
|-- bam
| |-- Pfeiffer2.bam -> /home/tboyarski/share/projects/tboyarski/gitRepo-LCR-BCCRC/Snakemake/buildArea/output/reBam/Pfeiffer2_realigned_sorted.bam
| `-- Pfeiffer2.bam.bai -> /home/tboyarski/share/projects/tboyarski/gitRepo-LCR- BCCRC/Snakemake/buildArea/output/reBam/Pfeiffer2_realigned_sorted.bam.bai
|-- fastq
|-- mPile
|-- reBam
| |-- Pfeiffer2_realigned_sorted.bam
| `-- Pfeiffer2_realigned_sorted.bam.bai
在这种情况下,您需要的只是“验证器”中的返回值,以及响应它的条件运算符。
我认为你已经有了这个,因为你必须在验证步骤中使用条件。不要使用它将文件名写入txt文件,只需将文件符号链接到最终位置并继续。
我的原始数据在reBamDIR中。 我存储在BamDIR中的最终数据。 我只将管道中此阶段的文件符号链接到bamDIR。 reBamDIR中有其他文件,但我不希望我的其他管道看到它们,所以,我将它们过滤掉。
我不确定如何实施“验证器”和你的条件,因为我不知道你的情况,我还在学习。只是尝试提供替代观点//方法。
from time import gmtime, strftime
rule indexBAM:
input:
expand("{outputDIR}/{reBamDIR}/{{samples}}{fileTAG}.bam", outputDIR=config["outputDIR"], reBamDIR=config["reBamDIR"], fileTAG=config["fileTAG"])
output:
expand("{outputDIR}/{reBamDIR}/{{samples}}{fileTAG}.bam.bai", outputDIR=config["outputDIR"], reBamDIR=config["reBamDIR"], fileTAG=config["fileTAG"]),
expand("{outputDIR}/{bamDIR}/{{samples}}.bam.bai", outputDIR=config["outputDIR"], bamDIR=config["bamDIR"]),
expand("{outputDIR}/{bamDIR}/{{samples}}.bam", outputDIR=config["outputDIR"], bamDIR=config["bamDIR"])
params:
bamDIR=config["bamDIR"],
outputDIR=config["outputDIR"],
logNAME="indexBAM." + strftime("%Y-%m-%d.%H-%M-%S", gmtime())
log:
"log/" + config["reBamDIR"]
shell:
"samtools index {input} {output[0]} " \
" 2> {log}/{params.logNAME}.stderr " \
"&& ln -fs $(pwd)/{output[0]} $(pwd)/{params.outputDIR}/{params.bamDIR}/{wildcards.samples}.bam.bai " \
"&& ln -fs $(pwd)/{input} $(pwd)/{params.outputDIR}/{params.bamDIR}/{wildcards.samples}.bam"
答案 2 :(得分:0)
**这不是你问题的答案,而是一个达到目标的建议。 **
我认为在管道运行期间修改yaml文件是不可能的 - 或者至少不是微不足道的。
就个人而言,当我运行snakemake工作流程时,我使用外部文件,我称之为#34;元数据"。它们包括一个配置文件,但也包含一个包含样本列表的标签文件(以及可能包含所述样本的其他信息)。配置文件包含一个参数,该参数是此文件的路径。
在这样的设置中,我建议您使用"规则a"输出包含所选样本的另一个选项卡文件,该文件的路径可以包含在配置文件中(即使它在启动工作流程时不存在)。规则b将该文件作为输入。
在你的情况下你可以:
config:
samples: "/path/to/samples.tab"
valid_samples: "/path/to/valid_samples.tab"
我不知道它是否有意义,因为它基于我自己的组织。我认为它很有用,因为它允许存储的信息不仅仅是样本名称,如果你有100个样本,它就更容易管理!