Nextflow 进程 (process) 彼此隔离。

输入项 (input) 定义从哪个通道 (channels) 接收输入数据。

一次只能定义一个输入项,并且它必须包含一个或多个输入。

输入项遵循以下语法:

input:
[from ] [attributes]
  • 定义以输入限定符和输入名称开头,
  • 关键字from和接收输入的实际通道。
  • 指定一些输入可选属性。

当输入名称与通道名称相同时,from可以省略声明的一部分。

输入限定符声明要接收的数据类型。Nextflow使用此信息来应用与每个限定符相关的语义规则,并根据目标执行平台(网格,云等)正确处理它。

可用的限定符是下表中列出的限定符:

预选赛 语义的
val 可以按进程脚本中的名称访问收到的输入值。
env 可以使用接收到的值来设置名为指定输入名称的环境变量。
file 可以将接收到的值作为文件来处理,并在执行上下文中对其进行适当的暂存。
path 可以将接收到的值作为路径来处理,从而在执行上下文中正确地暂存文件。
stdin 可以将接收到的值转发到流程stdin特殊文件。
tuple 可以处理具有上述限定符之一的一组输入值。
each 可以对输入集合中的每个条目执行该过程。

输入值

val限定词中,可以接收任何类型作为输入的数据。可以使用指定的输入名称在流程脚本中对其进行访问,如以下示例所示:

num = Channel.from( 1, 2, 3 )

process basicExample {
input:
val x from num

"echo process job $x"

}

在上面的示例中,该过程执行了三次,每次从通道接收到一个值num 并用于处理脚本。因此,它产生类似于以下所示的输出:

process job 3
process job 1
process job 2

通道(channel)保证数据项都以相同的顺序传递,但因为该方法以并行方式执行时,不能保证它们以相同的顺序进行处理。在上面的示例中,值3是在其他值之前处理的。

如果与val接收数据的通道具有相同的名称,则from可以省略该部分。

因此,上面的示例可以写成如下所示:

num = Channel.from( 1, 2, 3 )

process basicExample {
input:
val num

"echo process job $num"

}

输入文件

file限定词允许在进程执行中处理文件。Nextflow会将其暂存在流程执行目录中,并且可以使用输入声明中指定的名称在脚本中对其进行访问。例如:

proteins = Channel.fromPath( '/some/path/*.fa' )

process blastThemAll {
input:
file query_file from proteins

"blastp -query ${query_file} -db nr"

}

在上面的示例中,所有以后缀.fa结尾的文件都是通过通道发送的proteins

然后,这些文件将被该进程接收,该进程将对每个文件执行BLAST查询。

当文件输入名称与通道名称相同时,from输入声明的一部分可以省略。

因此,上面的示例可以写成如下所示:

proteins = Channel.fromPath( '/some/path/*.fa' )

process blastThemAll {
input:
file proteins

"blastp -query $proteins -db nr"

}

在上面的示例中,文件系统中的文件名没有被触及,即不知道文件名也可以访问该文件,因为可以使用指定了名称的变量在流程脚本中对其进行引用在输入文件的参数声明中。

在某些情况下,的任务需要使用名称固定的文件,而不必与实际提供的文件一起更改。在这种情况下,可以通过name在输入文件参数声明中指定属性来指定其名称,如以下示例所示:

input:
file query_file name 'query.fa' from proteins

或者使用较短的语法:

input:
file 'query.fa' from proteins

使用此方法,可以如下所示重写前面的示例:

proteins = Channel.fromPath( '/some/path/*.fa' )

process blastThemAll {
input:
file 'query.fa' from proteins

"blastp -query query.fa -db nr"

}

在此示例中发生的是,该进程接收到的每个文件都query.fa 在不同的执行上下文(即,执行作业的文件夹)中使用该名称暂存,并且启动了独立的进程执行。

小费

这可以在不同时间执行process命令,而不必担心文件名更改。换句话说,Nextflow可以帮助编写由执行环境独立且脱钩的管道任务。这也是为什么应尽可能避免在管道过程中使用引用文件的绝对或相对路径的原因。

多个输入文件

进程可以声明一个发出值集合而不是简单值的通道作为输入文件。

在这种情况下,由输入文件参数定义的脚本变量将保存文件列表。您可以如前所示使用它,引用列表中的所有文件,或者使用常用的方括号表示法访问特定条目。

当在输入参数中定义了目标文件名并且该过程接收到文件集合时,该文件名将附加一个数字后缀,以表示其在列表中的顺序位置。例如:

fasta = Channel.fromPath( "/some/path/*.fa" ).buffer(size:3)

process blastThemAll {
input:
file 'seq' from fasta

"echo seq*"

}

输出:

seq1 seq2 seq3
seq1 seq2 seq3
...

目标输入文件名可以包含*?通配符,可用于控制暂存文件的名称。下表显示了如何根据接收到的输入集合的基数替换通配符。

Cardinality Name pattern Staged file names
any * 命名为源文件
1 file*.ext file.ext
1 file?.ext file1.ext
1 file??.ext file01.ext
many file*.ext file1.ext, file2.ext, file3.ext, ..
many file?.ext file1.ext, file2.ext, file3.ext, ..
many file??.ext file01.ext, file02.ext, file03.ext, ..
many dir/* 命名为源文件,在dir子目录中创建
many dir??/* 命名为源文件,以逐步建立索引子目录例如创建dir01/dir02/等等。
many dir*/* 同上

以下片段显示了如何在输入文件声明中使用通配符:

fasta = Channel.fromPath( "/some/path/*.fa" ).buffer(size:3)

process blastThemAll {
input:
file 'seq?.fa' from fasta

"cat seq1.fa seq2.fa seq3.fa"

}

动态输入文件名

使用namefile子句或短字符串表示法指定输入文件名时,可以将其他输入值用作文件名字符串中的变量。例如:

process simpleCount {
input:
val x from species
file "${x}.fa" from genomes

"""
cat ${x}.fa | grep '>'
"""
}

在上面的示例中,使用x输入值的当前值设置输入文件名。

这允许使用与当前执行上下文一致的名称在脚本工作目录中暂存输入文件。

注意:

在大多数情况下,您不需要使用动态文件名,因为每个进程都在其自己的私有临时目录中执行,并且输入文件将由Nextflow自动登台到该目录中。这样可以保证具有相同名称的输入文件不会相互覆盖。

输入“路径”类型

path输入限定符被Nextflow版本19.10.0引入,这是一个简易替换为file限定符,因此它是后向兼容的语法和用于输入语义file如上所述。

filepathqualifier 之间的重要区别是,第一个期望输入的值是文件对象。当输入是其他类型时,它会自动转换为字符串并将其保存到临时文件中。在某些用例中这可能很有用,但在大多数情况下却是棘手的。

所述path限定词代替解释字符串值作为输入文件的路径位置,并自动转换为一个文件对象。

process foo {
input:
path x from '/some/data/file.txt'
"""
your_command --in $x
"""
}

注意

提供的输入值应该代表即字符串值的绝对路径位置 必须与前缀/字符或与受支持的协议的URI即file://http://s3://等,并且它不能包含特殊字符(例如\n,等)。

该选项stageAs使您可以控制如何在任务工作目录中命名文件,并提供特定的名称或名称模式,如“ 多个输入文件” 部分所述:

process foo {
input:
path x, stageAs: 'data.txt' from '/some/data/file.txt'
"""
your_command --in data.txt
"""
}

小费

所述path限定词应当优于file使用Nextflow 19.10.0或更高时,手柄处理输入文件。

输入“ stdin”

stdin输入限定允许您从一信道接收到所述值的转发 标准输入 由所述处理中执行的命令的。例如:

str = Channel.from('hello', 'hola', 'bonjour', 'ciao').map { it+'\n' }

process printAll {
input:
stdin str

"""
cat -
"""

}

它将输出:

hola
bonjour
ciao
hello

输入“ env”类型

env限定符允许定义基于从信道接收到的值的过程中的执行上下文的环境变量。例如:

str = Channel.from('hello', 'hola', 'bonjour', 'ciao')

process printEnv {

input:
env HELLO from str

'''
echo $HELLO world!
'''

}
hello world!
ciao world!
bonjour world!
hola world!

输入“设置”类型

警告

该组输入型已被弃用。请参阅元组。

输入“ tuple”

tuple预选赛中,您可以将多个参数一个参数的定义。当流程在输入中接收需要单独处理的值的元组时,这将很有用。元组中的每个元素都与具有tuple定义的相应元素相关联。例如:

values = Channel.of( [1, 'alpha'], [2, 'beta'], [3, 'delta'] )

process tupleExample {
input:
tuple val(x), file('latin.txt') from values

"""
echo Processing $x
cat - latin.txt > copy
"""

}

在上面的示例中,tuple参数用于定义值x和文件latin.txt,文件将从同一通道接收值。

tuple声明的项目可以通过使用下面的限定词来定义:valenvfilestdin

通过应用以下替换规则,可以使用较短的符号:

值(x) X
文件(x) (不支持)
文档名称’) ‘名称’
文件(x:’名称’) x:“姓名”
标准输入 ‘-‘
env(x) (不支持)

因此,前面的示例可以重写如下:

values = Channel.of( [1, 'alpha'], [2, 'beta'], [3, 'delta'] )

process tupleExample {
input:
tuple x, 'latin.txt' from values

"""
echo Processing $x
cat - latin.txt > copy
"""
}

可以按动态方式定义文件名,如“ 动态输入文件名”部分中所述。

输入中继器

each预选赛中,您可以重复流程的执行每个项目集合中,每收到一个新的数据的时间。例如:

sequences = Channel.fromPath('*.fa')
methods = ['regular', 'expresso', 'psicoffee']

process alignSequences {
input:
file seq from sequences
each mode from methods

"""
t_coffee -in $seq -mode $mode > result
"""
}

在上面的示例中,每次过程接收到序列文件作为输入时,该文件都会执行三个任务,这些任务运行带有不同mode参数值的T型咖啡对齐。当您需要为一组给定的参数重复相同的任务时,这很有用。

由于0.25+版以上的输入中继器也可以应用于文件。例如:

sequences = Channel.fromPath('*.fa')
methods = ['regular', 'expresso']
libraries = [ file('PQ001.lib'), file('PQ002.lib'), file('PQ003.lib') ]

process alignSequences {
input:
file seq from sequences
each mode from methods
each file(lib) from libraries

"""
t_coffee -in $seq -mode $mode -lib $lib > result
"""
}

注意

声明多个中继器时,将对它们的每个组合执行该过程。

在后面的示例中,对于sequences通道发出的任何序列输入文件,将执行6个比对,其中3个regular针对每个库文件使用该方法,其他3个expresso始终针对相同的库文件使用该方法。

暗示

如果需要在n个元组元素(而不是简单的值或文件)上重复执行过程,请创建一个通道,根据需要组合输入值以多次触发过程执行。在这方面,请参见Combinecrossphase运算符。

了解多个输入通道的工作方式

流程的关键特征是能够处理来自多个通道的输入。

当将两个或多个通道声明为过程输入时,过程将停止,直到存在完整的输入配置即。它从所有声明为输入的通道中接收输入值。

验证此条件后,它将消耗来自各个通道的输入值,并生成任务执行,然后重复相同的逻辑,直到一个或多个通道不再有内容。

这意味着通道值是一个接一个地连续消耗的,即使其他通道中还有其他值,第一个空通道也会导致进程执行停止。

例如:

process foo {
echo true
input:
val x from Channel.from(1,2)
val y from Channel.from('a','b','c')
script:
"""
echo $x and $y
"""
}

该过程foo执行两次,因为第一个输入通道仅提供两个值,因此c元素被丢弃。它打印:

1 and a
2 and b

警告

当使用Value通道(又称为Singleton通道)时,将应用不同的语义。

这种通道是通过Channel.value工厂方法创建的,或者在流程输入在from子句中指定简单值时隐式创建的。

根据定义,值通道绑定到单个值,并且可以无限制地读取该值而不消耗其内容。

这些属性使得将值通道与一个或多个(队列)通道混合时,不会影响仅取决于其他通道的过程终止,并且其内容会重复应用。

为了更好地理解此行为,请将前面的示例与以下示例进行比较:

process bar {
echo true
input:
val x from Channel.value(1)
val y from Channel.from('a','b','c')
script:
"""
echo $x and $y
"""
}

上面的代码段执行该bar过程三次,因为第一个输入是一个值通道,因此可以根据需要读取其内容多次。进程终止由第二通道的内容确定。它打印:

1 and a
1 and b
1 and c