代码之家  ›  专栏  ›  技术社区  ›  gminer23543

不同文件名的多个目录上的全局通配符

  •  0
  • gminer23543  · 技术社区  · 8 年前

    我正在尝试编写一个规则,该规则从不同的目录中获取两个文件,并将规则的输出放入与下面的文件结构相同的目录中:

    DIR_A 
        dir1    
            file1.clean.vcf  
        dir2  
            file2.clean.vcf  
        dir3
            file1.output.vcf
            file2.output.vcf
    

    到目前为止,我已经尝试使用glob_通配符:

    (DIR,NAME) = glob_wildcards("DIR_A/{dir}/{name}.clean.vcf") 
    input: expand("DIR_A/{dir}/{name}.clean.vcf", dir=DIR, name=NAME)
    output: "DIR_A/dir3/{name}.output.vcf
    

    但它抛出了一个错误:

    MissingInputException in line 80 of DIR_A:
    Missing input files for rule convert_output:
    
    DIR_A/dir1/file2.clean.vcf
    DIR_A/dir2/file1.clean.vcf
    

    将zip添加到输入:

    input: expand("DIR_A/{dir}/{name}.clean.vcf", zip, dir=DIR, name=NAME)
    

    如果$snakemake-s snakefile-n(干运行):

    rule conv_output:
    input: DIR_A/dir1/file1.clean.vcf, DIR_A/file2/file2.clean.vcf
    

    这被snakemake接受并防止了上述错误,但是现在file1.clean.vcf和file2.clean.vcf都是规则的输入,但是name通配符使规则每个文件运行一次。这最终是一个文件到一个文件的多个文件,而不是我正在寻找的一个到一个文件。

    有没有一种方法可以设置它,这样我就可以得到规则conv_输出的输出,从而对每个文件执行操作,然后将输出放到dir3中?任何帮助都将不胜感激!!

    1 回复  |  直到 8 年前
        1
  •  2
  •   Manavalan Gajapathy Pal    8 年前

    使用python,将输入vcf sample/filename配对到其路径,然后使用它在snakemake规则中指定输入路径。下面的示例适用于问题中给出的目录结构。

    from pathlib import Path   
    
    def pair_name_to_infiles():
        # get all *.clean.vcf files recursively under DIR_A
        vcf_path = Path('DIR_A').glob('**/*.clean.vcf')
    
        # pair vcf name to infile path using a dictionary
        vcf_infiles_dict = {}
        for f in vcf_path:
            vcf_name = f.name.replace('.clean.vcf', '')
            vcf_infiles_dict[vcf_name] = str(f)
    
        return vcf_infiles_dict
    
    
    # using function written in python code, map vcf name to their infile path
    vcf_infiles_dict = pair_name_to_infiles()
    
    
    rule all:
        input:
            expand('DIR_A/dir3/{vcf_name}.output.vcf', vcf_name=vcf_infiles_dict.keys())
    
    
    rule foo:
        input:
            lambda wildcards: vcf_infiles_dict[wildcards.vcf_name]
        output:
            'DIR_A/dir3/{vcf_name}.output.vcf'
        shell:
            'touch {output}'
    
    推荐文章