Snakemake-如何使用文件的每一行作为输入?

时间:2019-08-21 17:47:36

标签: python-3.x snakemake

我需要将文件tissuesused.txt的每一行用作snakemake中并行化规则的输入。我认为我总共要致电约48个职位。

for line in $(cat tissuesused.txt)
do
   echo "Sorting $line.phen_fastqtl.bed to $line/$line.pheno.bed..."
   bedtools sort -header -i $line/$line.phen_fastqtl.bed > $line/$line.pheno.bed 
   echo "bgzipping $line/$line.pheno.bed..."
   bgzip -f $line/$line.pheno.bed
   #figure out where tabix outputs
   echo "Indexing $line/$line.pheno.bed.gz..."
   tabix -p bed $line/$line.pheno.bed.gz
done

我将如何在snakemake中进行此操作?我在网上找不到任何东西。这项工作发生在管道的中途,因此我不知道如何在蛇文件的顶部定义一个尚不存在的文件的功能。我只想创建一个字符串列表,每个字符串都包含在tissuesused.txt中发现的一种人体组织的缩写。我发现一个section in the snakemake docs看起来像是相关的,但不确定如何将其应用于我的案例。预先谢谢你。

编辑: 这是我到目前为止的内容,不确定是否可以使用

def fileAsList(file):
    with open(file) as f:
        for line in f:
            lis = []
            spl = line.split()
            lis.append(spl[0])
        return lis
...
rule sort_zip_ind_pheno:
    input:
        tis=fileAsList("tissuesused.txt"),
        chk=".make_tis_dirs.chkpnt"
    output:
        touch(".sort_zip_ind_pheno.chkpnt")
    shell:
        "bedtools sort -header -i {input.tis}/{input.tis}.phen_fastqtl.bed > \
        {input.tis}/{input.tis}.pheno.bed;"
        "bgzip -f {input.tis}/{input.tis}.pheno.bed;"
        "tabix -p bed {input.tis}/{input.tis}.pheno.bed.gz"

请告诉我这是否合理。

1 个答案:

答案 0 :(得分:1)

我认为您要寻找的是checkpoints在Snakemake中。看一下这个例子:

checkpoint get_tissue:
    output:
        "tissuesused.txt"
    run:
        with open(output[0], 'a') as f:
            for i in range(9):
                f.write(f"{i}\n")


rule read_tissue:
    output:
        "tissue_{n}.txt"
    shell:
        """
        echo "this is tissue {wildcards.n}" > {output}
        """


def read_tissues_output(wildcards):
    with open(checkpoints.get_tissue.get().output[0]) as f:
        samples = [sample for sample in f.read().split('\n') if len(sample) > 0]  # we dont want empty lines
        return expand("tissue_{sample}.txt", sample=samples)

rule all:
    input:
        read_tissues_output

并使用

运行它

snakemake --until all

规则全部使用read_tissues_output作为输入函数(正如您在问题中指定的一样)。然后,此函数尝试打开检查点get_tissue的输出,如果该输出不存在,它将生成该检查点。输出存在后,函数将读取文件,并返回我们要生成的文件(tissue_{1-10})。规则read_tissue可以为我们生成(并行)然后生成这些文件。

修改

tissueused.txt:

WHLBLD
TESTIS
THYROID

Snakefile

def read_tissues_output():
    with open('tissuesused.txt') as f:
        samples = [sample for sample in f.read().split('\n') if len(sample) > 0]  # we dont want empty lines
        return expand("tissue_{sample}.txt", sample=samples)

rule all:
    input:
        read_tissues_output()


rule read_tissue:
    output:
        "tissue_{n}.txt"
    shell:
        """
        echo "this is tissue {wildcards.n}" > {output}
        """