Parte 3: Chamada conjunta em uma coorte¶
Tradução assistida por IA - saiba mais e sugira melhorias
Anteriormente, você construiu um pipeline de chamada de variantes por amostra que processou os dados de cada amostra de forma independente. Agora vamos estendê-lo para implementar a chamada conjunta de variantes, conforme descrito na Parte 1 (caso de uso multi-amostra).
Como começar a partir desta seção
Esta seção do curso pressupõe que você completou a Parte 1: Visão Geral do Método, Parte 2: Chamada de variantes por amostra e tem um pipeline genomics.nf funcionando.
Se você não completou a Parte 2 ou quer começar do zero para esta parte, pode usar a solução da Parte 2 como ponto de partida.
Execute estes comandos de dentro do diretório nf4-science/genomics/:
cp solutions/part2/genomics-2.nf genomics.nf
cp solutions/part2/nextflow.config .
cp solutions/part2/modules/* modules/
Isso fornece um fluxo de trabalho completo de chamada de variantes por amostra. Você pode testar se ele executa com sucesso executando o seguinte comando:
Tarefa¶
Nesta parte do curso, vamos estender o fluxo de trabalho para fazer o seguinte:
- Gerar um arquivo de índice para cada arquivo BAM de entrada usando Samtools
- Executar o GATK HaplotypeCaller em cada arquivo BAM de entrada para gerar um GVCF de chamadas de variantes genômicas por amostra
- Coletar todos os GVCFs e combiná-los em um armazenamento de dados GenomicsDB
- Executar genotipagem conjunta no armazenamento de dados GVCF combinado para produzir um VCF em nível de coorte
Isso implementa o método descrito na Parte 1: Visão Geral do Método (segunda seção cobrindo o caso de uso multi-amostra) e se baseia diretamente no fluxo de trabalho produzido pela Parte 2: Chamada de variantes por amostra.
Plano da lição¶
Dividimos isso em duas etapas:
- Modificar a etapa de chamada de variantes por amostra para produzir um GVCF. Isso abrange a atualização de comandos e saídas do processo.
- Adicionar uma etapa de genotipagem conjunta que combina e genotipa os GVCFs por amostra.
Isso introduz o operador
collect(), closures Groovy para construção de linha de comando e processos com múltiplos comandos.
Isso automatiza as etapas da segunda seção da Parte 1: Visão geral do método, onde você executou esses comandos manualmente em seus contêineres.
Dica
Certifique-se de estar no diretório de trabalho correto:
cd /workspaces/training/nf4-science/genomics
1. Modificar a etapa de chamada de variantes por amostra para produzir um GVCF¶
O pipeline da Parte 2 produz arquivos VCF, mas a chamada conjunta requer arquivos GVCF. Precisamos ativar o modo de chamada de variantes GVCF e atualizar a extensão do arquivo de saída.
Lembre-se do comando de chamada de variantes GVCF da Parte 1:
gatk HaplotypeCaller \
-R /data/ref/ref.fasta \
-I /data/bam/reads_mother.bam \
-O reads_mother.g.vcf \
-L /data/ref/intervals.bed \
-ERC GVCF
Comparado ao comando base HaplotypeCaller que encapsulamos na Parte 2, as diferenças são o parâmetro -ERC GVCF e a extensão de saída .g.vcf.
1.1. Informar ao HaplotypeCaller para emitir um GVCF e atualizar a extensão de saída¶
Abra o arquivo de módulo modules/gatk_haplotypecaller.nf para fazer duas alterações:
- Adicione o parâmetro
-ERC GVCFao comando GATK HaplotypeCaller; - Atualize o caminho do arquivo de saída para usar a extensão
.g.vcfcorrespondente, conforme convenção do GATK.
Certifique-se de adicionar uma barra invertida (\) no final da linha anterior quando adicionar -ERC GVCF.
Também precisamos atualizar o bloco de saída para corresponder à nova extensão de arquivo.
Como mudamos a saída do comando de .vcf para .g.vcf, o bloco output: do processo deve refletir a mesma mudança.
1.2. Atualizar a extensão do arquivo de saída no bloco de saídas do processo¶
Também precisamos atualizar a configuração de publicação e saída do fluxo de trabalho para refletir as novas saídas GVCF.
1.3. Atualizar os alvos de publicação para as novas saídas GVCF¶
Como agora estamos produzindo GVCFs em vez de VCFs, devemos atualizar a seção publish: do fluxo de trabalho para usar nomes mais descritivos.
Também organizaremos os arquivos GVCF em seu próprio subdiretório para maior clareza.
Agora atualize o bloco de saída para corresponder.
1.4. Atualizar o bloco de saída para a nova estrutura de diretórios¶
Também precisamos atualizar o bloco output para colocar os arquivos GVCF em um subdiretório gvcf.
Com o módulo, alvos de publicação e bloco de saída todos atualizados, podemos testar as alterações.
1.5. Executar o pipeline¶
Execute o fluxo de trabalho para verificar se as alterações funcionam.
Saída do comando
A saída do Nextflow parece a mesma de antes, mas os arquivos .g.vcf e seus arquivos de índice agora estão organizados em subdiretórios.
Conteúdo do diretório (links simbólicos encurtados)
results/
├── gvcf/
│ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf
│ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx
│ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf
│ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx
│ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf
│ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx
└── indexed_bam/
├── reads_father.bam -> */9a/c7a873*/reads_father.bam
├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai
├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam
├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai
├── reads_son.bam -> */cc/fbc705*/reads_son.bam
└── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai
Se você abrir um dos arquivos GVCF e percorrê-lo, poderá verificar que o GATK HaplotypeCaller produziu arquivos GVCF conforme solicitado.
Conclusão¶
Quando você altera o nome do arquivo de saída de um comando de ferramenta, o bloco output: do processo e a configuração de publicação/saída devem ser atualizados para corresponder.
O que vem a seguir?¶
Aprenda a coletar o conteúdo de um canal e passá-los para o próximo processo como uma única entrada.
2. Adicionar uma etapa de genotipagem conjunta¶
Agora precisamos coletar os GVCFs por amostra, combiná-los em um armazenamento de dados GenomicsDB e executar a genotipagem conjunta para produzir um VCF em nível de coorte.
Conforme abordado na Parte 1, esta é uma operação de duas ferramentas: GenomicsDBImport combina os GVCFs, depois GenotypeGVCFs produz as chamadas de variantes finais.
Vamos encapsular ambas as ferramentas em um único processo chamado GATK_JOINTGENOTYPING.
Lembre-se dos dois comandos da Parte 1:
gatk GenomicsDBImport \
-V reads_mother.g.vcf \
-V reads_father.g.vcf \
-V reads_son.g.vcf \
-L /data/ref/intervals.bed \
--genomicsdb-workspace-path family_trio_gdb
O primeiro comando recebe os GVCFs por amostra e um arquivo de intervalos, e produz um armazenamento de dados GenomicsDB.
O segundo recebe esse armazenamento de dados, um genoma de referência, e produz o VCF final em nível de coorte.
O URI do contêiner é o mesmo do HaplotypeCaller: community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867.
2.1. Configurar as entradas¶
O processo de genotipagem conjunta precisa de dois tipos de entradas que ainda não temos: um nome de coorte arbitrário e as saídas GVCF coletadas de todas as amostras agrupadas.
2.1.1. Adicionar um parâmetro cohort_name¶
Precisamos fornecer um nome arbitrário para a coorte.
Mais adiante na série de treinamento você aprenderá como usar metadados de amostra para esse tipo de coisa, mas por enquanto apenas declaramos um parâmetro CLI usando params.
Usaremos este parâmetro para nomear o arquivo de saída final.
2.1.2. Adicionar um valor padrão para cohort_name no perfil de teste¶
Também adicionamos um valor padrão para o parâmetro cohort_name no perfil de teste:
| nextflow.config | |
|---|---|
Em seguida, precisaremos reunir as saídas por amostra para que possam ser processadas juntas.
2.1.3. Reunir as saídas do HaplotypeCaller entre as amostras¶
Se conectássemos o canal de saída de GATK_HAPLOTYPECALLER diretamente no novo processo, o Nextflow chamaria o processo em cada GVCF de amostra separadamente.
Queremos agrupar todos os três GVCFs (e seus arquivos de índice) para que o Nextflow os entregue todos juntos a uma única chamada de processo.
Podemos fazer isso usando o operador de canal collect().
Adicione as seguintes linhas ao corpo do workflow, logo após a chamada a GATK_HAPLOTYPECALLER:
Detalhando isso:
- Pegamos o canal de saída de
GATK_HAPLOTYPECALLERusando a propriedade.out. - Como nomeamos as saídas usando
emit:na seção 1, podemos selecionar os GVCFs com.vcfe os arquivos de índice com.idx. Sem saídas nomeadas, teríamos que usar.out[0]e.out[1]. - O operador
collect()agrupa todos os arquivos em um único elemento, entãoall_gvcfs_chcontém todos os três GVCFs juntos, eall_idxs_chcontém todos os três arquivos de índice juntos.
Podemos coletar os GVCFs e seus arquivos de índice separadamente (em vez de mantê-los juntos em tuplas) porque o Nextflow preparará todos os arquivos de entrada juntos para execução, então os arquivos de índice estarão presentes ao lado dos GVCFs.
Dica
Você pode usar o operador view() para inspecionar o conteúdo dos canais antes e depois de aplicar operadores de canal.
2.2. Escrever o processo de genotipagem conjunta e chamá-lo no fluxo de trabalho¶
Seguindo o mesmo padrão que usamos na Parte 2, escreveremos a definição do processo em um arquivo de módulo, o importaremos no fluxo de trabalho e o chamaremos nas entradas que acabamos de preparar.
2.2.1. Construir uma string para dar a cada GVCF um argumento -V¶
Antes de começarmos a preencher a definição do processo, há uma coisa a resolver.
O comando GenomicsDBImport espera um argumento -V separado para cada arquivo GVCF, assim:
gatk GenomicsDBImport \
-V reads_mother.bam.g.vcf \
-V reads_father.bam.g.vcf \
-V reads_son.bam.g.vcf \
...
Se escrevêssemos -V ${all_gvcfs_ch}, o Nextflow simplesmente concatenaria os nomes de arquivo e essa parte do comando ficaria assim:
Mas precisamos que a string fique assim:
Importante, precisamos construir essa string dinamicamente a partir de quaisquer arquivos que estejam no canal coletado. O Nextflow (via Groovy) fornece uma maneira concisa de fazer isso:
Detalhando isso:
all_gvcfs.collect { gvcf -> "-V ${gvcf}" }itera sobre cada caminho de arquivo e adiciona-Vantes dele, produzindo["-V A.g.vcf", "-V B.g.vcf", "-V C.g.vcf"]..join(' ')os concatena com espaços:"-V A.g.vcf -V B.g.vcf -V C.g.vcf".- O resultado é atribuído a uma variável local
gvcfs_line(definida comdef), que podemos interpolar no template de comando.
Esta linha vai dentro do bloco script: do processo, antes do template de comando.
Você pode colocar código Groovy arbitrário entre script: e as aspas triplas de abertura """ do template de comando.
Então você poderá se referir a toda essa string como gvcfs_line no bloco script: do processo.
2.2.2. Preencher o módulo para o processo de genotipagem conjunta¶
Em seguida, podemos abordar a escrita do processo completo.
Abra modules/gatk_jointgenotyping.nf e examine o esboço da definição do processo.
Vá em frente e preencha a definição do processo usando as informações fornecidas acima, depois verifique seu trabalho contra a solução na aba "Depois" abaixo.
| modules/gatk_jointgenotyping.nf | |
|---|---|
Há várias coisas que vale a pena destacar aqui.
Como anteriormente, várias entradas são listadas mesmo que os comandos não as referenciem diretamente: all_idxs, ref_index e ref_dict.
Listá-las garante que o Nextflow prepare esses arquivos no diretório de trabalho ao lado dos arquivos que aparecem nos comandos, que o GATK espera encontrar com base em convenções de nomenclatura.
A variável gvcfs_line usa a closure Groovy descrita acima para construir os argumentos -V para GenomicsDBImport.
Este processo executa dois comandos em série, assim como você faria no terminal.
GenomicsDBImport combina os GVCFs por amostra em um armazenamento de dados, depois GenotypeGVCFs lê esse armazenamento de dados e produz o VCF final em nível de coorte.
O armazenamento de dados GenomicsDB (${cohort_name}_gdb) é um artefato intermediário usado apenas dentro do processo; ele não aparece no bloco de saída.
Uma vez que você tenha completado isso, o processo está pronto para uso. Para usá-lo no fluxo de trabalho, você precisará importar o módulo e adicionar uma chamada de processo.
2.2.3. Importar o módulo¶
Adicione a instrução de importação a genomics.nf, abaixo das instruções de importação existentes:
O processo agora está disponível no escopo do fluxo de trabalho.
2.2.4. Adicionar a chamada do processo¶
Adicione a chamada a GATK_JOINTGENOTYPING no corpo do fluxo de trabalho, após as linhas collect():
| genomics.nf | |
|---|---|
| genomics.nf | |
|---|---|
O processo agora está totalmente conectado. Em seguida, configuramos como as saídas são publicadas.
2.3. Configurar o tratamento de saídas¶
Precisamos publicar as saídas do VCF conjunto. Adicione alvos de publicação e entradas de bloco de saída para os resultados de genotipagem conjunta.
2.3.1. Adicionar alvos de publicação para o VCF conjunto¶
Adicione o VCF conjunto e seu índice à seção publish: do fluxo de trabalho:
Agora atualize o bloco de saída para corresponder.
2.3.2. Adicionar entradas de bloco de saída para o VCF conjunto¶
Adicione entradas para os arquivos VCF conjunto. Vamos colocá-los na raiz do diretório de resultados, já que esta é a saída final.
Com o processo, alvos de publicação e bloco de saída todos no lugar, podemos testar o fluxo de trabalho completo.
2.4. Executar o fluxo de trabalho¶
Execute o fluxo de trabalho para verificar se tudo funciona.
Saída do comando
As duas primeiras etapas estão em cache da execução anterior, e a nova etapa GATK_JOINTGENOTYPING é executada uma vez nas entradas coletadas de todas as três amostras.
O arquivo de saída final, family_trio.joint.vcf (e seu índice), está no diretório de resultados.
Conteúdo do diretório (links simbólicos encurtados)
results/
├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf
├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx
├── gvcf/
│ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf
│ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx
│ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf
│ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx
│ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf
│ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx
└── indexed_bam/
├── reads_father.bam -> */9a/c7a873*/reads_father.bam
├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai
├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam
├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai
├── reads_son.bam -> */cc/fbc705*/reads_son.bam
└── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai
Se você abrir o arquivo VCF conjunto, poderá verificar que o fluxo de trabalho produziu as chamadas de variantes esperadas.
Você agora tem um fluxo de trabalho de chamada conjunta de variantes automatizado e totalmente reproduzível!
Nota
Tenha em mente que os arquivos de dados que fornecemos cobrem apenas uma pequena porção do cromossomo 20. O tamanho real de um conjunto de chamadas de variantes seria contado em milhões de variantes. É por isso que usamos apenas pequenos subconjuntos de dados para fins de treinamento!
Conclusão¶
Você sabe como coletar saídas de um canal e agrupá-las como uma única entrada para outro processo. Você também sabe como construir uma linha de comando usando closures Groovy e como executar múltiplos comandos em um único processo.
O que vem a seguir?¶
Dê um grande tapinha nas costas! Você completou o curso Nextflow para Genômica.
Vá para o resumo final do curso para revisar o que você aprendeu e descobrir o que vem a seguir.