当前位置: 首页 > 知识库问答 >
问题:

使用混合通配符输出文件

史弘博
2023-03-14
rule all:
    input: "SA.txt", "SA_T1.txt", "SA_T2.txt",
        "SB.txt", "SB_T1.txt", "SB_T2.txt", "SB_T3.txt"

现在我想编写一个类似这样的规则来生成这些文件:

rule X:
    output: N="S{X}.txt", T="S{X}_T{Y}.txt"
    (etc.)

但是SnakeMake要求两个输出模板都具有相同的通配符,而这些模板没有。此外,即使SnakeMake可以处理多个通配符,它也可能希望为S{X}_T{Y}.txt模板找到一个与之匹配的文件名,但我希望该文件匹配{X}与第一个模板的{X}匹配的所有文件,即我希望output.t是一个列表,而不是单个文件。因此,似乎这样做的方法是:

def myExpand(T, wildcards):
    T = T.replace("{X}", wildcards.X)
    T = [T.replace("{Y}", S) for S in theXYs[wildcards.X]]
    return T

rule X:
    output: N="S{X}.txt", T=lambda wildcards: myExpand("S{X}_T{Y}.txt", wildcards)
    (etc.)

但是我不能这样做,因为lambda函数不能在输出部分中使用。

在我看来,这似乎是为了支持output语句上的lambda函数,提供一个通配符字典,其中填充了output语句中已经解析过的部分中的值。

需要通配符Y的值,因为其他规则为那些具有通配符Y的文件提供了输入。

我的规则知道从数据库读取到python字典中的数据时,它需要处理的Y(和X)的不同值。

为了充实这一讨论,我相信这是一个合理的讨论,让我们假设一个可能出现的简单情况。假设对于许多人中的每一个人,您有N(>=2)个肿瘤VCF文件,就像我所做的那样,并且您希望编写一个规则来产生N+1个输出文件,每个肿瘤一个输出文件加上一个与该人相关的文件。使用通配符X表示人员ID,使用通配符Y表示人员X中的肿瘤ID。假设操作是将所有肿瘤VCF文件中存在的所有变体放入人员输出VCF文件,并将所有其他变体放入对应的肿瘤输出文件中。假设一个程序从N个输入文件中生成所有N+1个文件。你怎么写规则?

你想要这个:

rule:
    output: COMMON="{X}.common.vcf", INDIV="{X}.{Y}.indiv.vcf"
    input: "{X}.{Y}.vcf"
    shell: """
        getCommonAndIndividualVariants --inputs {input} \
        --common {output.COMMON} --indiv {output.INDIV}
        """

但这违反了输出通配符的规则。

我这样做的方法是使用两个规则,第一个规则的输出模板带有更多的通配符,第二个规则的模板带有更少的通配符,并让第二个规则创建临时输出文件,这些文件由第一个规则重命名为最终名称:

rule A:
    output: "{X}.{Y}.indiv.vcf"
    input: "{X}.common.vcf"
    run: "for infile in {input}: os.system('mv '+infile+'.tmp'+' '+infile)"

rule B:
    output: "{X}.common.vcf"
    input: lambda wildcards: \
        expand("{X}.{Y}.vcf", **wildcards, Y=getYfromDB(wildcards["X"]))
    params: OUT=lambda wildcards: \
        expand("{X}.{Y}.indiv.vcf.tmp", Y=getYfromDB(wildcards["X"]))
    shell: """
        getCommonAndIndividualVariants --inputs {input} \
        --common {output} --indiv {params.OUT}
        """

共有1个答案

徐智渊
2023-03-14

我不知道您的工作流的其余部分是什么样子的,最好的解决方案是依赖于上下文的。

如何将规则分成两个,一个创建“sa.txt”、“sa_t1.txt”、“sa_t2.txt”和另一个创建“sb.txt”、“sb_t1.txt”、“sb_t2.txt”、“sb_t3.txt”

另一种可能是只让{X}文件在输出指令中,但让规则创建其他文件,即使它们不在输出指令中。如果{Y}文件是DAG的一部分,则不起作用。

第三个也可能是最好的解决方案是在X规则和要求X输出的规则中使用聚合通配符。

那么解决办法就是

rule X:
    output: N="S{X_prime}.txt", T="S{Y_prime}.txt"

需要这些文件的规则如下所示:

rule all:
    input:
        expand("S{X_prime}", X_prime="A_T1 A_T2".split()),
        expand("S{Y_prime}", Y_prime="B_T1 B_T2 B_T3".split())
list_of_all_valid_X_prime_values = "A_T1 A_T2".split()
list_of_all_valid_Y_prime_values = "B_T1 B_T2 B_T3".split()

wildcard_constraints:
    X_prime = "({})".format("|".join(list_of_all_valid_X_prime_values))
    Y_prime = "({})".format("|".join(list_of_all_valid_Y_prime_values))

rule all:
    ...
 类似资料:
  • 问题内容: 上面的代码不允许您将元素添加到列表中,通配符只能用作方法中的签名,同样不能用于添加,而只能用于访问。在这种情况下,以上目的是什么? 问题答案: 假设您有一个接口和两个类: 然后,您将得到返回结果列表的类: 当您需要“协变量返回”,但是返回集合而不是自己的对象时,这是一个很好的解决方案。最大的好处是,当独立于ITest接口使用ATest和BTest时,不必强制转换对象。但是,使用ITes

  • 问题内容: 我想获取带有通配符的搜索模式的文件名列表。喜欢: 我怎样才能做到这一点? 问题答案: 您可以这样做: 注意 :如果目录中包含以开头的文件,则默认情况下将不匹配它们。例如,考虑包含和的目录: 这直接来自这里:http : //docs.python.org/library/glob.html

  • 问题内容: 在以下情况下,我遇到了仿制药的问题,请参见以下内联注释,以了解我的问题: 问题答案: //Intuitively I would expect this to mean that test is set containing objects //that subclass AbstractGroup Set<? extends AbstractGroup> test; 不,这意味着它是

  • 问题内容: 我有一个返回定义为的方法: 我不清楚此方法的实际实现,但是当我尝试这样做时: 我收到以下编译时错误消息: Map类型的put(String,capture#9-of?)方法不适用于参数(String,String) 问题是什么?是什么类型的吗? 提前致谢。 问题答案: 通配符的意思是“值类型参数可以是任何东西”- 并不 意味着“您可以像使用任何想要的东西一样使用它”。换句话说,a 作为

  • 我有以下任务在我的 任务zipConfiguration(type:Zip){def myDir=project(':SomeProject').projectDir.toString()'/build/libs/'from myDir archiveName'Output.Zip'destinationDirectory=file($buildDir/libs”)} 项目的的将始终具有一个版本化

  • 问题内容: 我想知道是否以及如何在路径定义中使用通配符。我想更深入地查找一个文件夹并尝试使用*,但这不起作用。 我想访问随机文件夹中的文件。Folderstructure是这样的: 我试过的 先感谢您! 问题答案: 我认为不可能以这种方式使用通配符。我建议您对任务使用如下方式: