Nextflow中如何合并输入与参数创建新变量?
问题:Nextflow Process中无法结合Input与Parameter生成可用变量
场景描述
尝试在Nextflow的process中创建结合input段dna参数与parameter段内容的变量g_label,供script段执行命令使用。相关代码与配置如下:
Process代码
nextflow.enable.dsl=2 process VariantCall { container 'the_container' input: val(dna) tuple val(meta), path(in_bam), path(in_bam_bai) output: tuple val(meta), path('out.vcf') publishDir "${params.publish_dir}/VariantCalling/${meta}/${dna}", mode: 'copy', pattern: '*.vcf' g_label = "${params.VC}.${dna}.general.label" script: """ the_variant_caller \ -l ${g_label} -o out.vcf """ }
params.json配置
{ "VC":{ "nDNA":{ "general": { "label": "", "cov_thresh": 0 } }, "mtDNA":{ "general": { "label": "MT", "cov_thresh": 0 } } }
工作流代码
workflow VariantCall_Module { take: dna in_bam main: VariantCall( dna, in_bam ) emit: vcf = VariantCall.out }
遇到的问题
无论如何定义g_label,均会报错:
ERROR ~ Error executing process > 'TheModule:VariantCalling_nDNA (1)'
Caused by:
No such variable: g_label -- Check script '././modules/variant-calling-ndna/../variant-call-utils/processes.nf' at line: 21
尝试过以下方式,未解决问题:
- 将
g_label定义放在script块内,报错变为No such variable: dna - 使用
def g_label = "${params.VC}.${dna}.general.label"定义变量,仍报错
注:dna变量在publishDir语句中可正常使用,但无法传递到自定义变量中。
解决方案
核心问题分析
- 作用域限制:process的input变量(如
dna)仅能在script块内通过字符串插值直接使用,或在publishDir/when等支持Nextflow表达式的段中使用;process顶层无法直接访问input变量。 - 参数取值错误:
"${params.VC}.${dna}.general.label"是字符串拼接,无法实际访问params嵌套结构的属性值,需用Groovy动态属性访问语法。
正确实现方式
方式1:在script块内用Groovy动态取值
将变量定义放在script块内,通过Groovy语法动态获取嵌套参数值:
process VariantCall { container 'the_container' input: val(dna) tuple val(meta), path(in_bam), path(in_bam_bai) output: tuple val(meta), path('out.vcf') publishDir "${params.publish_dir}/VariantCalling/${meta}/${dna}", mode: 'copy', pattern: '*.vcf' script: def g_label = params.VC[dna].general.label """ the_variant_caller \ -l ${g_label} \ -o out.vcf """ }
方式2:用env段定义环境变量复用
若需多处复用变量,可通过env段定义,利用Nextflow表达式解析:
process VariantCall { container 'the_container' input: val(dna) tuple val(meta), path(in_bam), path(in_bam_bai) output: tuple val(meta), path('out.vcf') publishDir "${params.publish_dir}/VariantCalling/${meta}/${dna}", mode: 'copy', pattern: '*.vcf' env: G_LABEL = params.VC[dna].general.label script: """ the_variant_caller \ -l \$G_LABEL \ -o out.vcf """ }
关键说明
- 动态访问嵌套参数:
params.VC[dna]会根据dna的实际值(如nDNA/mtDNA)动态获取对应子结构,再提取general.label的值。 - script块内的Groovy变量:用
def定义的变量属于Groovy变量,可直接通过${g_label}插值到shell命令;若用env段定义,shell中需用$G_LABEL访问环境变量。
内容的提问来源于stack exchange,提问作者Ulf90
相关产品推荐
相关产品推荐

