在我的 Nextflow 工作流程中,我需要处理类似于以下示例的文件。
a.vcf.gz
a.vcf.gz.tbi
b.vcf.gz
b.vcf.gz.tbi
c.vcf.gz
c.vcf.gz.tbi
特别是,我需要创建一个 channel ,它将使用以下结构输出它们:
[
["id": "test"],
["a.vcf.gz", "b.vcf.gz", "c.vcf.gz"],
["a.vcf.gz.tbi", "b.vcf.gz.tbi", "c.vcf.gz.tbi"]
]
这意味着单个 map 的元组、*.vcf.gz
文件的一个元组和*.vcf.gz.tbi
文件的一个元组。
我的问题是,根据我对文档的阅读,不清楚如何从以三个一组顺序发出项目的 channel 创建它。
为了简单起见,我使用 Channel.fromFilePairs
从对中收集文件:
ch_input = Channel
.fromFilePairs("*{.vcf.gz,.vcf.gz.tbi}")
这就是我陷入困境的地方。我得到的最接近的是通过废弃 fromFilePairs
并使用 groupTuple
:
ch_input = Channel
.fromPath("*.vcf.gz*")
.map {
file ->
def fmeta = ["id": "test"]
value = file.extension == "gz" ? "vcf": "tbi"
[value, file]
}.groupTuple()
println ch_input.view()
这给出:
[tbi, [/Users/einar/Coding/a.vcf.gz.tbi, /Users/einar/Coding/c.vcf.gz.tbi, /Users/einar/Coding/einar/b.vcf.gz.tbi]]
[vcf, [/Users/einar/Coding/b.vcf.gz, /Users/einar/Coding/a.vcf.gz, /Users/einar/Coding/c.vcf.gz]]
这仍然与我想要的相距甚远,而且更脆弱,因为它依赖于文件扩展名。
Channel.multiMap
接近我想要的,但是它生成多个 channel ,而我需要一个 channel 。
如何正确完成此操作?
编辑:
这是另一种尝试,它得到了我想要的,但对我来说它看起来有点老套和脆弱:
ch_input = Channel
.fromPath("*.vcf*")
.map{
file ->
[file.extension, file]
}.groupTuple()
.map {
it ->
def fmeta = ["id": "test"]
[fmeta, it[1].flatten()]
}.groupTuple()
.map{
it ->
[it[0], it[1][0], it[1][1]]
}
println ch_input.view()
最佳答案
要获得您想要的东西,您需要 collect运算符为您提供 value channel :
Channel
.fromFilePairs( '/path/to/files/*.vcf.gz{,.tbi}' )
.collect { sample, indexed_vcf -> [ indexed_vcf ] }
.map {
def fmeta = [ "id": "test" ]
[ fmeta, it*.first(), it*.last() ]
}
.view()
如果没有详细信息,很难说,但通常您不需要将索引文件与实际的 VCF 文件分开。如果此 channel 直接用作进程输入,我的首选是更改输入声明,以便我可以使用类似这样的内容:
Channel
.fromPath( '/path/to/files/*.vcf.gz{,.tbi}' )
.collect()
.map {
def fmeta = ["id": "test"]
[ fmeta, it ]
}
.view()
关于groovy - Nextflow:将 fromFilePairs 的输入转换为 (map, list_pair_1, list_pair_2) 的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72659723/