Warning
Some of the translations on the training portal are out of date. The translated material may be incomplete or incorrect. We plan to update the translations later this year. In the meantime, please try to work through the English-language material if you can.
12. Modularização¶
A definição de bibliotecas modulares simplifica a escrita de fluxos de trabalho complexos de análise de dados, além tornar o reuso de processos mais fácil.
Ao usar o exemplo hello.nf da seção de introdução, nós converteremos os processos do fluxo de trabalho em módulos e, em seguida, executaremos estes processos dentro do escopo workflow de diferentes formas.
12.1 Módulos¶
A DSL2 do Nextflow permite a definição de scripts de módulos autônomos que podem ser incluídos e compartilhados em vários fluxos de trabalho. Cada módulo pode conter sua própria definição de process ou workflow.
12.1.1 Importando módulos¶
Os componentes definidos no script do módulo podem ser importados para outros scripts do Nextflow usando a instrução include. Isso permite que você armazene esses componentes em arquivos separados para que possam ser reutilizados em vários fluxos de trabalho.
Usando o exemplo hello.nf, podemos fazer isso:
- Criando um arquivo chamado
modules.nfno mesmo diretório dohello.nf. - Copiando e colando as duas definições de processo para
SPLITLETTERSeCONVERTTOUPPERemmodules.nf. - Removendo as definições
processno scripthello.nf. - Importando os processos de
modules.nfdentro do scripthello.nfem qualquer lugar acima da definição deworkflow:
Note
Em geral, você deve usar caminhos relativos para definir a localização dos scripts do módulo usando o prefixo ./.
Exercise
Crie um arquivo modules.nf com os processos previamente definidos no script hello.nf. Em seguida, remova esses processos de hello.nf e adicione as definições include mostradas acima.
Solution
O script hello.nf deve ser similar a este:
Você deve ter o seguinte código em ./modules.nf:
Agora nós modularizamos os processos, o que faz com que o código seja reutilizável.
12.1.2 Importações múltiplas¶
Se um script de módulo Nextflow contiver várias definições de process, elas também podem ser importadas usando uma única instrução include, conforme mostrado no exemplo abaixo:
12.1.3 Apelidos dos módulos¶
Ao incluir um componente de um módulo, é possível especificar um apelido para os processos usando a declaração as. Isso permite a inclusão e a invocação do mesmo componente várias vezes usando diferentes apelidos:
Exercise
Salve o trecho anterior como hello.2.nf, e tente adivinhar qual saída será mostrada na tela.
Solution
A saída de hello.2.nf deve ser semelhante a essa:
N E X T F L O W ~ version 23.04.1
Launching `hello.2.nf` [crazy_shirley] DSL2 - revision: 99f6b6e40e
executor > local (6)
[2b/ec0395] process > SPLITLETTERS_one (1) [100%] 1 of 1 ✔
[d7/be3b77] process > CONVERTTOUPPER_one (1) [100%] 2 of 2 ✔
[04/9ffc05] process > SPLITLETTERS_two (1) [100%] 1 of 1 ✔
[d9/91b029] process > CONVERTTOUPPER_two (2) [100%] 2 of 2 ✔
WORLD!
HELLO
HELLO
WORLD!
Tip
Você pode armazenar cada processo em arquivos separados em subpastas separadas ou combinados em um arquivo grande (ambos são válidos). Você pode encontrar exemplos disso em repositórios públicos, como no tutorial de RNA-Seq da Seqera ou em fluxos de trabalho do nf-core, como o nf-core/rnaseq.
12.2 Definição de saída¶
O Nextflow permite o uso de definições de saída alternativas em fluxos de trabalho para simplificar seu código.
No exemplo básico anterior (hello.nf), definimos os nomes dos canais para especificar a entrada para o próximo processo:
Note
Nós movemos o greeting_ch para o escopo workflow para este exercício.
Também podemos definir explicitamente a saída de um canal para outro usando o atributo .out, removendo completamente as definições de canal:
Se um processo define dois ou mais canais de saída, cada canal pode ser acessado indexando o atributo .out, por exemplo, .out[0], .out[1], etc. Em nosso exemplo, temos apenas a saída [0]'th:
Alternativamente, a definição de output do processo permite o uso da instrução emit para definir um identificador nomeado que pode ser usado para referenciar o canal no escopo externo.
Por exemplo, tente adicionar a instrução emit no processo CONVERTTOUPPER em seu arquivo modules.nf:
| modules.nf | |
|---|---|
Em seguida, altere o escopo workflow em hello.nf para chamar essa saída nomeada específica (observe o .upper adicionado):
| hello.nf | |
|---|---|
12.2.1 Usando saídas canalizadas¶
Outra maneira de lidar com as saídas no escopo workflow é usar pipes |.
Exercise
Tente alterar o script do fluxo de trabalho para o trecho abaixo:
Aqui usamos um pipe que passa a saída de um processo como um canal para o próximo processo sem a necessidade de aplicar .out ao nome do processo.
12.3 Definição do escopo workflow¶
O escopo workflow permite a definição de componentes que definem a invocação de um ou mais processos ou operadores:
Por exemplo, o trecho acima define um workflow chamado meu_fluxo_de_trabalho, que pode ser chamado por meio de outra definição de workflow.
Note
Certifique-se de que seu arquivo modules.nf é o que contém o emit no processo CONVERTTOUPPER.
Warning
Um componente de um fluxo de trabalho pode acessar qualquer variável ou parâmetro definido no escopo externo. No exemplo em execução, também podemos acessar params.greeting diretamente na definição de workflow.
12.3.1 Entradas no escopo workflow¶
Um componente workflow pode declarar um ou mais canais de entrada usando a instrução take. Por exemplo:
Note
Quando a instrução take é usada, a definição workflow precisa ser declarada dentro do bloco main.
A entrada para o workflow pode então ser especificada como um argumento:
12.3.2 Saídas no escopo workflow¶
Um bloco workflow pode declarar um ou mais canais de saída usando a instrução emit. Por exemplo:
Como resultado, podemos usar a notação meu_fluxo_de_trabalho.out para acessar as saídas de meu_fluxo_de_trabalho na chamada workflow.
Também podemos declarar saídas nomeadas dentro do bloco emit.
O resultado do trecho de código acima pode ser acessado usando meu_fluxo_de_trabalho.out.meus_dados.
12.3.3 Chamando escopos workflows nomeados¶
Dentro de um script main.nf (chamado hello.nf em nosso exemplo), também podemos ter vários fluxos de trabalho. Nesse caso, podemos chamar um fluxo de trabalho específico ao executar o código. Para isso, usamos a chamada de ponto de entrada -entry <nome_do_flux_de_trabalho>.
O trecho a seguir tem dois fluxos de trabalho nomeados (meu_fluxo_de_trabalho_um e meu_fluxo_de_trabalho_dois):
Você pode escolher qual fluxo de trabalho é executado usando o sinalizador entry:
12.3.4 Escopos de parâmetros¶
Um script de módulo pode definir um ou mais parâmetros ou funções personalizadas usando a mesma sintaxe de qualquer outro script Nextflow. Usando os exemplos mínimos abaixo:
Script do módulo (./modules.nf) | |
|---|---|
Script principal (./hello.nf) | |
|---|---|
A execução de hello.nf deve imprimir:
Como destacado acima, o script imprimirá Hola mundo! em vez de Hello world! porque os parâmetros herdados do contexto de inclusão são substituídos pelas definições no arquivo de script onde estão sendo incluídos.
Info
Para evitar que sejam ignorados, os parâmetros do fluxo de trabalho devem ser definidos no início do script antes de qualquer declaração de inclusão.
A opção addParams pode ser usada para estender os parâmetros do módulo sem afetar o escopo externo. Por exemplo:
A execução do script principal acima deve imprimir:
12.4 Notas de migração DSL2¶
Para visualizar um resumo das alterações introduzidas quando o Nextflow migrou da DSL1 para a DSL2, consulte as notas de migração da DSL2 na documentação oficial do Nextflow.