在Snakemake中使用多个文件名作为通配符

时间:2018-01-25 13:03:55

标签: input wildcard snakemake

我正在尝试创建一个规则来在bedtools中实现snakemake,这将closest一个包含另一个目录中的文件的文件。

我所拥有的是/home/bedfiles目录下的20个床位文件:

1A.bed , 2B_83.bed , 3f_33.bed ...

我想要的是,在/home/bedfiles目录下,有20个修改过的床文件:

1A_modified,  2B_83_modified , 3f_33_modified ...

所以bash命令是:

filelist='/home/bedfiles/*.bed'
for mfile in $filelist;
do
bedtools closest -a /home/other/merged.txt -b ${mfile} > ${mfile}_modified

因此,此命令将在_modified目录中生成/home/bedfiles扩展名的文件。

我想用Snakemake实现这个,但是我一直有语法错误,我不知道如何修复。我的试用期是:

第1步:获取目录中第一部分床文件

FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')]

第2步:定义输出名称和文件夹

MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART)

第3步:在rule all

中撰写
rule all:
   input: MODIFIED

步骤4:制定具体规则以实施“最接近的床铺”

rule closest:

    input:
        input1 = "/home/other/merged.txt" , \
        input2 = expand("/home/bedfiles/{first}.bed", first=FIRSTPART) 

    output:
        expand("/home/bedfiles/{first}_modified", first=FIRSTPART)  

    shell:
        """ bedtools closest -a {input.input1} -b {input.input2} > {output} """

它会在规则all的行中抛出错误,输入:

invalid syntax

您知道如何绕过此错误或以其他任何方式实现它吗?

PS:无法逐个写出文件的名称。

2 个答案:

答案 0 :(得分:2)

删除expandinputoutputclosest定义中对input.input2的号召。您目前正在传递20个文件名为output的向量和20个文件名为closest的向量。

也就是说,您的规则closest目前正在尝试运行一次并创建20个文件;而它应该运行20次并每次创建一个文件。

input.input2中,您希望output成为单个文件,并且每次运行该规则时FIRSTPART = [f.split(".")[0] for f in os.listdir("/home/bedfiles") if f.endswith('.bed')] print("These are the input files:") print([f + ".bed" for f in FIRSTPART]) MODIFIED = expand("/home/bedfiles/{first}_modified", first=FIRSTPART) print("These will be created") print(MODIFIED) rule all: input: MODIFIED rule closest: message: """ Converts /home/other/merged.txt and /some/dir/xyz.bed into /some/dir/xyz_modified """ input: input1 = "/home/other/merged.txt", input2 = "{prefix}.bed" output: "{prefix}_modified" shell: """ bedtools closest -a {input.input1} -b {input.input2} > {output} """ 都是单个文件:

mkdir bedfiles                                                                  
touch bedfiles/{a,b,c,d}.bed

这是一个实验:

将自己移到临时目录中,并在该目录中执行以下操作:

Snakefile

然后将名为import os import os.path import re input_dir = "bedfiles" input_files = [os.path.join(input_dir, f) for f in os.listdir(input_dir)] print(input_files) output_files = [re.sub(".bed$", "_modified", f) for f in input_files] print(output_files) rule all: input: output_files rule mover: input: "{prefix}.bed" output: "{prefix}_modified" shell: """ cp {input} {output} """ 的文件添加到当前目录中,该文件包含以下代码

snakemake

然后在命令行使用@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME%.. @rem agregado por marcgaso set GRADLE_OPTS="-Dorg.gradle.native.dir=/tmp" **strong text** 运行它。 Snakemake以目标为导向;它解决了如何根据现有文件制作所需的输出。

答案 1 :(得分:0)

简单一句:无效语法是指在input1 = "/home/other/merged.txt"之后缺少{{1}} 希望能帮助到你 马克