5. Canais¶
Canais são uma estrutura de dados chave do Nextflow que permite a implementação de fluxos de trabalho computacionais utilizando paradigmas funcional e reativo com base no paradigma de programação Dataflow.
Eles são usados para conectar logicamente tarefas entre si ou para implementar transformações de dados de estilo funcional.
5.1 Tipos de canais¶
O Nextflow distingue dois tipos diferentes de canais: canais de fila e canais de valor.
5.1.1 Canal de fila¶
Um canal de fila é uma fila assíncrona unidirecional FIFO (First-in-First-out, o primeiro a entrar, é o primeiro a sair) que conecta dois processos ou operadores.
- assíncrono significa que as operações ocorrem sem bloqueio.
- unidirecional significa que os dados fluem do gerador para o consumidor.
- FIFO significa que os dados são entregues na mesma ordem em que são produzidos. Primeiro a entrar, primeiro a sair.
Um canal de fila é criado implicitamente por definições de saída de um processo ou usando fábricas de canal, como o Channel.of ou Channel.fromPath.
Tente os seguintes trechos de código:
Clique no ícone no código para ver explicações.
- Use a função
println
embutida no Nextflow por padrão para imprimir o conteúdo do canalcanal
- Aplique o operador
view
no canalcanal
para imprimir cada emissão desse canal
Exercise
Tente executar este trecho de código. Você pode fazer isso criando um novo arquivo .nf
ou editando um arquivo .nf
já existente.
5.1.2 Canais de valor¶
Um canal de valor (também conhecido como canal singleton), por definição, está vinculado a um único valor e pode ser lido quantas vezes for necessário sem consumir seu conteúdo. Um canal de valor
é criado usando a fábrica de canal value ou por operadores que retornam um valor apenas, como first, last, collect, count, min, max, reduce, e sum.
Para entender melhor a diferença entre canais de valor e de fila, salve o trecho abaixo como exemplo.nf
.
exemplo.nf | |
---|---|
Ao rodar o script, ele imprime apenas 2, como você pode ver abaixo:
Um processo só instanciará uma tarefa quando houver elementos a serem consumidos de todos os canais fornecidos como entrada para ele. Como canal1
e canal2
são canais de fila, e o único elemento de canal2
foi consumido, nenhuma nova instância de processo será iniciada, mesmo se houver outros elementos a serem consumidos em canal1
.
Para usar o único elemento em canal2
várias vezes, podemos usar Channel.value
como mencionado acima, ou usar um operador de canal que retorna um único elemento como first()
abaixo:
Além disso, em muitas situações, o Nextflow converterá implicitamente variáveis em canais de valor quando forem usadas em uma chamada de processo. Por exemplo, quando você chama um processo com um parâmetro de fluxo de trabalho (params.exemplo
) que possui um valor de string, ele é automaticamente convertido em um canal de valor.
5.2 Fábricas de canal¶
Estes são comandos do Nextflow para criar canais que possuem entradas e funções implícitas esperadas.
5.2.1 value()
¶
A fábrica de canal value
é utilizada para criar um canal de valor. Um argumento opcional não nulo
pode ser especificado para vincular o canal a um valor específico. Por exemplo:
- Cria um canal de valor vazio
- Cria um canal de valor e vincula uma string a ele
- Cria um canal de valor e vincula a ele um objeto de lista que será emitido como uma única emissão
5.2.2 of()
¶
A fábrica Channel.of
permite a criação de um canal de fila com os valores especificados como argumentos.
A primeira linha neste exemplo cria uma variável canal
que contém um objeto de canal. Este canal emite os valores especificados como parâmetro na fábrica de canal of
. Assim, a segunda linha imprimirá o seguinte:
A fábrica de canal Channel.of
funciona de maneira semelhante ao Channel.from
(que foi descontinuado), corrigindo alguns comportamentos inconsistentes do último e fornecendo um melhor manuseio quando um intervalo de valores é especificado. Por exemplo, o seguinte funciona com um intervalo de 1 a 23:
5.2.3 fromList()
¶
A fábrica de canal Channel.fromList
cria um canal emitindo os elementos fornecidos por um objeto de lista especificado como um argumento:
5.2.4 fromPath()
¶
A fábrica de canal fromPath
cria um canal de fila emitindo um ou mais arquivos correspondentes ao padrão glob especificado.
Este exemplo cria um canal e emite tantos itens quanto arquivos com extensão csv
existirem na pasta ./data/meta
. Cada elemento é um objeto de arquivo implementando a interface Path do Java.
Tip
Dois asteriscos, ou seja, **
, funcionam como *
, mas cruzam os limites do diretório. Essa sintaxe geralmente é usada para percorrer caminhos completos. Os colchetes especificam uma coleção de subpadrões.
Nome | Descrição |
---|---|
glob | Quando true interpreta caracteres * , ? , [] e {} como glob wildcards, caso contrário, os trata como caracteres normais (padrão: true ) |
type | Tipo de caminho retornado, ou file , dir ou any (padrão: file ) |
hidden | Quando true inclui arquivos ocultos nos caminhos resultantes (padrão: false ) |
maxDepth | Número máximo de níveis de diretório a serem visitados (padrão: no limit ) |
followLinks | Quando true links simbólicos são seguidos durante a travessia da árvore de diretórios, caso contrário, eles são gerenciados como arquivos (padrão: true ) |
relative | Quando true os caminhos de retorno são relativos ao diretório de topo mais comum (padrão: false ) |
checkIfExists | Quando true lança uma exceção quando o caminho especificado não existe no sistema de arquivos (padrão: false ) |
Saiba mais sobre a sintaxe dos padrões glob neste link.
Exercise
Use a fábrica de canal Channel.fromPath
para criar um canal emitindo todos os arquivos com o sufixo .fq
no diretório data/ggal/
e qualquer subdiretório, além dos arquivos ocultos. Em seguida, imprima os nomes dos arquivos.
5.2.5 fromFilePairs()
¶
A fábrica de canal fromFilePairs
cria um canal emitindo os pares de arquivos correspondentes a um padrão glob fornecido pelo usuário. Os arquivos correspondentes são emitidos como tuplas, nas quais o primeiro elemento é a chave de agrupamento do par correspondente e o segundo elemento é a lista de arquivos (classificados em ordem lexicográfica).
Ele produzirá uma saída semelhante à seguinte:
[liver, [/workspace/gitpod/nf-training/data/ggal/liver_1.fq, /workspace/gitpod/nf-training/data/ggal/liver_2.fq]]
[gut, [/workspace/gitpod/nf-training/data/ggal/gut_1.fq, /workspace/gitpod/nf-training/data/ggal/gut_2.fq]]
[lung, [/workspace/gitpod/nf-training/data/ggal/lung_1.fq, /workspace/gitpod/nf-training/data/ggal/lung_2.fq]]
Warning
O padrão glob precisa conter pelo menos um caractere curinga de estrela (*
).
Nome | Descrição |
---|---|
type | Tipo de caminhos retornados, ou file , dir ou any (padrão: file ) |
hidden | Quando true inclui arquivos ocultos nos caminhos resultantes (padrão: false ) |
maxDepth | Número máximo de níveis de diretório a serem visitados (padrão: no limit ) |
followLinks | Quando true links simbólicos são seguidos durante a travessia da árvore de diretórios, caso contrário, eles são gerenciados como arquivos (padrão: true ) |
size | Define o número de arquivos que cada item emitido deve conter (padrão: 2 ). Use -1 para qualquer número |
flat | Quando true os arquivos correspondentes são produzidos como únicos elementos nas tuplas emitidas (padrão: false ) |
checkIfExists | Quando true lança uma exceção quando o caminho especificado não existe no sistema de arquivos (padrão: false ) |
Exercise
Use a fábrica de canal fromFilePairs
para criar um canal emitindo todos os pares de leituras em fastq no diretório data/ggal/
e imprima-os. Em seguida, use a opção flat: true
e compare a saída com a execução anterior.
5.2.6 fromSRA()
¶
A fábrica de canal Channel.fromSRA
permite consultar o banco de dados NCBI SRA e retorna um canal que emite os arquivos FASTQ correspondentes aos critérios de seleção especificados.
A consulta pode ser ID(s) de projeto(s) ou número(s) de acesso suportado(s) pela API do NCBI ESearch.
Info
Esta função agora requer uma chave de API que você só pode obter fazendo login em sua conta NCBI.
Instruções para login do NCBI e aquisição de chave
- Vá para: https://www.ncbi.nlm.nih.gov/
- Clique no botão "Login" no canto superior direito para entrar no NCBI. Siga suas instruções.
- Uma vez em sua conta, clique no botão no canto superior direito, geralmente seu ID.
- Vá para Account settings
- Role para baixo até a seção "API Key Management".
- Clique em "Create an API Key".
- A página será atualizada e a chave será exibida onde estava o botão. Copie sua chave.
Por exemplo, o trecho a seguir imprimirá o conteúdo de um ID de projeto NCBI:
Substitua <Sua chave de API aqui>
com sua chave de API.
Isso deve imprimir:
[SRR3383346, [/vol1/fastq/SRR338/006/SRR3383346/SRR3383346_1.fastq.gz, /vol1/fastq/SRR338/006/SRR3383346/SRR3383346_2.fastq.gz]]
[SRR3383347, [/vol1/fastq/SRR338/007/SRR3383347/SRR3383347_1.fastq.gz, /vol1/fastq/SRR338/007/SRR3383347/SRR3383347_2.fastq.gz]]
[SRR3383344, [/vol1/fastq/SRR338/004/SRR3383344/SRR3383344_1.fastq.gz, /vol1/fastq/SRR338/004/SRR3383344/SRR3383344_2.fastq.gz]]
[SRR3383345, [/vol1/fastq/SRR338/005/SRR3383345/SRR3383345_1.fastq.gz, /vol1/fastq/SRR338/005/SRR3383345/SRR3383345_2.fastq.gz]]
// (o restante foi omitido)
Vários IDs de acesso podem ser especificados usando um objeto lista:
[ERR908507, [/vol1/fastq/ERR908/ERR908507/ERR908507_1.fastq.gz, /vol1/fastq/ERR908/ERR908507/ERR908507_2.fastq.gz]]
[ERR908506, [/vol1/fastq/ERR908/ERR908506/ERR908506_1.fastq.gz, /vol1/fastq/ERR908/ERR908506/ERR908506_2.fastq.gz]]
[ERR908505, [/vol1/fastq/ERR908/ERR908505/ERR908505_1.fastq.gz, /vol1/fastq/ERR908/ERR908505/ERR908505_2.fastq.gz]]
Info
Os pares de leituras são gerenciados implicitamente e são retornados como uma lista de arquivos.
É fácil usar este canal como uma entrada usando a sintaxe usual do Nextflow. O código abaixo cria um canal contendo duas amostras de um estudo SRA público e executa o FASTQC nos arquivos resultantes. Veja:
Se você deseja executar o fluxo de trabalho acima e não possui o fastqc instalado em sua máquina, não esqueça o que aprendeu na seção anterior. Execute este fluxo de trabalho com -with-docker biocontainers/fastqc:v0.11.5
, por exemplo.
5.2.7 Arquivos de texto¶
O operador splitText
permite dividir strings de várias linhas ou itens de arquivo de texto, emitidos por um canal de origem em blocos contendo n linhas, que serão emitidos pelo canal resultante. Veja:
- Instrui o Nextflow a criar um canal a partir do caminho
data/meta/random.txt
- O operador
splitText
divide cada item em pedaços de uma linha por padrão. - Veja o conteúdo do canal.
Você pode definir o número de linhas em cada bloco usando o parâmetro by
, conforme mostrado no exemplo a seguir:
Info
O operador subscribe
permite a execução de funções definidas pelo usuário cada vez que um novo valor é emitido pelo canal de origem.
Uma clausura opcional pode ser especificada para transformar os blocos de texto produzidos pelo operador. O exemplo a seguir mostra como dividir arquivos de texto em blocos de 10 linhas e transformá-los em letras maiúsculas:
Você também pode fazer contagens para cada linha:
Por fim, você também pode usar o operador em arquivos simples (fora do contexto do canal):
5.2.8 Valores separados por vírgula (.csv)¶
O operador splitCsv
permite analisar itens de texto formatados em CSV (Comma-separated value) emitidos por um canal.
Em seguida, ele os divide em registros ou os agrupa como uma lista de registros com um comprimento especificado.
No caso mais simples, basta aplicar o operador splitCsv
a um canal que emite arquivos de texto ou entradas de texto no formato CSV. Por exemplo, para visualizar apenas a primeira e a quarta colunas:
Quando o CSV começa com uma linha de cabeçalho definindo os nomes das colunas, você pode especificar o parâmetro header: true
que permite referenciar cada valor pelo nome da coluna, conforme mostrado no exemplo a seguir:
Como alternativa, você pode fornecer nomes de cabeçalho personalizados especificando uma lista de strings no parâmetro de cabeçalho, conforme mostrado abaixo:
Você também pode processar vários arquivos CSV ao mesmo tempo:
Tip
Observe que você pode alterar o formato de saída simplesmente adicionando um delimitador diferente.
Por fim, você também pode operar em arquivos CSV fora do contexto do canal:
Exercise
Tente inserir leituras fastq no fluxo de trabalho do RNA-Seq anterior usando .splitCsv
.
Solution
Adicione um arquivo de texto CSV contendo o seguinte, como uma entrada de exemplo com o nome "fastq.csv":
gut,/workspace/gitpod/nf-training/data/ggal/gut_1.fq,/workspace/gitpod/nf-training/data/ggal/gut_2.fq
Em seguida, substitua o canal de entrada para as leituras em script7.nf
, alterando as seguintes linhas:
Para uma entrada de fábrica de canal splitCsv:
Por fim, altere a cardinalidade dos processos que usam os dados de entrada. Por exemplo, para o processo de quantificação, mude de:
Para:
Repita o procedimento acima para a etapa fastqc.
Agora o fluxo de trabalho deve ser executado a partir de um arquivo CSV.
5.2.9 Valores separados por tabulação (.tsv)¶
A análise de arquivos TSV funciona de maneira semelhante, basta adicionar a opção sep: '\t'
no contexto do splitCsv
:
Exercise
Tente usar a técnica de separação por tabulação no arquivo data/meta/regions.tsv
, mas imprima apenas a primeira coluna e remova o cabeçalho.
5.3 Formatos de arquivo mais complexos¶
5.3.1 JSON¶
Também podemos analisar facilmente o formato de arquivo JSON usando o oeprador de canal splitJson
.
O operador splitJson
suporta arranjos JSON:
Objetos JSON:
E inclusive arranjos JSON com objetos JSON!
Arquivos contendo dados em formato JSON também podem ser analisados:
5.3.2 YAML¶
Isso também pode ser usado como uma forma de analisar arquivos YAML:
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: pass_vafqc_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: pass_stripy_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: pass_manual_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: other_region_selection_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: ace_information_gained
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R1
feature: concordance_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: pass_vafqc_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: pass_stripy_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: pass_manual_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: other_region_selection_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: ace_information_gained
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R2
feature: concordance_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R3
feature: pass_vafqc_flag
pass_flag: "TRUE"
- patient_id: ATX-TBL-001-GB-01-105
region_id: R3
feature: pass_stripy_flag
pass_flag: "FALSE"
ATX-TBL-001-GB-01-105 -- pass_vafqc_flag
ATX-TBL-001-GB-01-105 -- pass_stripy_flag
ATX-TBL-001-GB-01-105 -- pass_manual_flag
ATX-TBL-001-GB-01-105 -- other_region_selection_flag
ATX-TBL-001-GB-01-105 -- ace_information_gained
ATX-TBL-001-GB-01-105 -- concordance_flag
ATX-TBL-001-GB-01-105 -- pass_vafqc_flag
ATX-TBL-001-GB-01-105 -- pass_stripy_flag
ATX-TBL-001-GB-01-105 -- pass_manual_flag
ATX-TBL-001-GB-01-105 -- other_region_selection_flag
ATX-TBL-001-GB-01-105 -- ace_information_gained
ATX-TBL-001-GB-01-105 -- concordance_flag
ATX-TBL-001-GB-01-105 -- pass_vafqc_flag
ATX-TBL-001-GB-01-105 -- pass_stripy_flag
5.3.3 Armazenamento em módulos de analisadores sintáticos¶
A melhor maneira de armazenar scripts com analisadores é mantê-los em um arquivo de módulo Nextflow.
Digamos que não temos um operador de canal JSON, mas criamos uma função para isso. O arquivo parsers.nf
deve conter a função parseArquivoJson
. Veja o conteúdo abaixo:
ATX-TBL-001-GB-01-105 tem pass_stripy_flag como coluna
ATX-TBL-001-GB-01-105 tem ace_information_gained como coluna
ATX-TBL-001-GB-01-105 tem concordance_flag como coluna
ATX-TBL-001-GB-01-105 tem pass_vafqc_flag como coluna
ATX-TBL-001-GB-01-105 tem pass_manual_flag como coluna
ATX-TBL-001-GB-01-105 tem other_region_selection_flag como coluna
O Nextflow usará isso como uma função personalizada dentro do escopo workflow
.
Tip
Você aprenderá mais sobre arquivos de módulo posteriormente na seção de Modularização desse tutorial.