说,我从一堆这样的文件开始:
group_1
sample1_content.txt
sample2_content.txt
sample3_content.txt
group_2
sample2_content.txt
sample3_content.txt
sample4_content.txt
group_3
sample1_content.txt
sample2_content.txt
sample5_content.txt
我有处理这些规则以按样本聚合文件的规则:
rule aggregate_by_sample:
input: expand('{group}/{sample}_content.txt')
output: '{sample}_allcontent.txt'
shell: "cat {input} | some_command > {output}"
我希望此规则的输入为:
group_1/sample1_content.txt, group_3/sample1_content.txt
group_1/sample2_content.txt, group_2/sample2_content.txt, group_3/sample2_content.txt
group_1/sample3_content.txt, group_2/sample3_content.txt
group_2/sample4_content.txt
group_3/sample5_content.txt
并生成以下输出文件:
sample1_allcontent.txt
sample2_allcontent.txt
sample3_allcontent.txt
sample4_allcontent.txt
sample5_allcontent.txt
至此,我想使用这些输出文件。因此,此规则可以类似于:
rule process_by_sample:
input: <list of all sample_allcontent files>
output: final_output.txt
shell: "cat {input} | some_other_command > {output}"
我的问题是:我怎样才能让snakemake等到它完成对aggregate_by_sample
规则中的所有文件的处理,然后将输出文件集用于规则process_by_sample
?我探索了通过将aggregate_by_sample
作为检查点来实现检查点的想法,但是我应该使用“目录”作为输出,因为我不知道apriori将产生多少个输出文件。但是我不能这样做,因为我的输出文件名使用通配符,snakemake抱怨Wildcards in input files cannot be determined from output files
。
由于文件已经存在,您可以使用glob_wildcards获取文件系统上的组/样本列表。使用它,您可以进一步处理输入文件。
这是我的(未试验的)想法:
wc = glob_wildcards('{group}/{sample}_content.txt')
samples_to_group = {}
for samp, group in zip(wc.group, wc.sample):
if samp not in samples_to_group:
samples_to_group[samp] = []
samples_to_group.append(group)
# now samples_to_group is a map of which groups are present for each sample
rule all:
input: "final_output.txt"
rule aggregate_by_sample:
input: expand('{group}/{sample}_content.txt',
group=samples_to_group[wildcards.sample],
allow_missing=True)
output: '{sample}_allcontent.txt'
shell: "cat {input} | some_command > {output}"
rule process_by_sample:
input: expand('{sample}_allcontent.txt', sample=samples_to_group.keys())
output: final_output.txt
shell: "cat {input} | some_other_command > {output}"
如果另一个规则正在生成文件,则必须使用检查点。