Guia do Desenvolvedor
Este guia fornece documentação detalhada para os scripts Python usados no pipeline do ViralQC. Destina-se a desenvolvedores que desejam entender a lógica interna, escolhas de implementação e o fluxo de execução da ferramenta.
Os scripts estão localizados em viralqc/scripts/python/ e são orquestrados por workflows do Snakemake.
Gerenciamento de datasets (Datasets)
Estes scripts são usados pelos comandos get-nextclade-datasets e get-blast-database para baixar e preparar dados de referência.
get_github_dataset.py
Propósito: Baixa diretórios específicos de datasets de um repositório GitHub sem usar a API do GitHub (para evitar limites de taxa).
Execução: Chamado por get_public_datasets.smk ao processar vírus configurados como github.
Detalhes de Implementação:
Sem Uso de API: Em vez de usar a API do GitHub, baixa o arquivo compactado do repositório via
https://codeload.github.com/.../zip/refs/heads/main.Extração Seletiva: Faz o stream do arquivo zip e extrai apenas os arquivos que correspondem ao
dataset-pathsolicitado.Achatamento de Estrutura: Lida com a remoção da pasta raiz (ex:
repo-main/) para colocar os arquivos diretamente no diretório de destino.
jsonl_to_gff.py
Propósito: Converte relatórios de anotação JSONL do NCBI Datasets para o formato GFF3, garantindo compatibilidade com o Nextclade.
Execução: Chamado por get_blast_database.smk após baixar dados do NCBI RefSeq.
Funções Principais:
clean_cds_name(cds_name): Sanitiza nomes de CDS removendo caracteres especiais, truncando para 20 caracteres e padronizando a formatação. Isso é crucial porque o Nextclade pode falhar com nomes de genes complexos, duplicados ou muito longos.jsonl_to_gff(...):Validação: Verifica se os comprimentos das CDS são múltiplos de 3. Se não, o número de acesso é marcado como inválido e excluído.
Agrupamento: Agrupa entradas de CDS divididas (ex: genes unidos) por nome para criar características gênicas únicas.
Gene vs CDS: Se os dados de CDS estiverem ausentes, tenta criar uma característica de gene usando o comprimento total do genoma (se divisível por 3).
get_minimizer_index.py
Propósito: Gera um arquivo JSON de índice de minimizadores a partir de arquivos FASTA de referência, permitindo que o Nextclade mapeie sequências para datasets externos (hospedados no GitHub).
Execução: Chamado por get_public_datasets.smk para datasets hospedados no GitHub.
Detalhes de Implementação:
Origem: Esta é uma adaptação simplificada do script
minimizer.pydo projeto Nextclade.Personalização: A função
fasta_readfoi modificada para incluir o nome do dataset nas anotações do registro de sequência. Isso garante que o índice gerado associe corretamente minimizadores de sequência com seus caminhos de datasets locais correspondentes.
Pipeline de Análise
Estes scripts são executados durante o fluxo de trabalho principal vqc run para processar sequências, identificar vírus e avaliar a qualidade.
format_nextclade_sort.py
Propósito: Processa a saída do nextclade sort para vincular datasets identificados com seus caminhos de arquivos locais e identificar sequências que não corresponderam a nenhum conjunto de dados.
Execução: Executado imediatamente após nextclade sort em run_analysis.smk.
Funções Principais:
map_datasets_to_local_paths(...): Lê a configuração YAML para construir um mapeamento entre nomes de datasets remotos (ex: do Nextclade) e caminhos de armazenamento local.format_nextclade_output(...): Mescla resultados de classificação “local” e “externo”. Adiciona uma colunalocalDatasetapontando para o diretório do vírus identificado.write_unmapped_sequences(...): Extrai sequências que não têm conjunto de dados atribuído (localDataseté NaN) e grava seus nomes emunmapped_sequences.txtpara análise subsequente do BLAST.
blast_wrapper.py
Propósito: Um wrapper em torno do comando blastn para lidar com segurança com cabeçalhos FASTA contendo espaços.
Execução: Executado pela regra blast em run_analysis.smk para sequências que não foram identificadas pelo Nextclade.
Detalhes de Implementação:
Sanitização: O BLAST pode truncar cabeçalhos no primeiro espaço, levando a incompatibilidades de ID em etapas de pós processamento. Este script verifica espaços nos cabeçalhos.
Fluxo de Renomeação:
Se espaços forem encontrados, gera um FASTA temporário onde as sequências são renomeadas para índices simples (1, 2, 3…).
Salva um arquivo de mapeamento (
mapping.tsv) vinculando índices aos cabeçalhos originais.Executa o BLAST com o arquivo renomeado.
Restaura os cabeçalhos originais no TSV de saída do BLAST usando o arquivo de mapeamento.
reorder_cds.py
Propósito: Reordena a string cdsCoverage na saída TSV do Nextclade para corresponder à ordem dos genes definida no arquivo GFF.
Execução: Executado após cada execução do nextclade run.
Lógica:
O Nextclade emite genes em ordem alfabética e omite genes com zero de cobertura.
Este script lê o GFF para estabelecer a ordem canônica dos genes (posição de
start).Analisa o
cdsCoverageexistente (formatoGene:Cov,...), reordena-o e insereGene:0.0para quaisquer genes ausentes. Isso garante ordenação consistente das colunas para processamento posterior.
post_process_nextclade.py
Propósito: O script central de agregação que combina resultados do Nextclade, BLAST e análises genéricas em um relatório final. Calcula métricas de qualidade categóricas (notas A-D) e produz a saída final (TSV, CSV ou JSON).
Execução: O passo final da regra post_process_nextclade.
Gerenciamento de Memória e Geradores:
Este script é projetado para processar datasets massivos (ex: milhões de sequências) com uma pegada de memória constante para saídas CSV/TSV.
Carregamento Preguiçoso (Lazy Loading) com Geradores: A função
format_dfsé implementada como um Gerador Python. Em vez de retornar uma lista de todos os DataFrames (o que carregaria todos os arquivos na RAM), elayields(produz) um DataFrame processado por vez.Lógica: Itera pela lista de arquivos de entrada. Para cada arquivo, lê os dados, enriquece com metadados, otimiza tipos, entrega ao consumidor e imediatamente deleta a referência e força a “coleta de lixo” (garbage collection).
Escrita em Fluxo (Streamed Writing): A função
write_combined_df(e sua auxiliar_write_csv_tsv_output) consome este gerador. Itera sobre o gerador, escrevendo cada pedaço produzido no disco imediatamente usandomode='a'(append/anexar).Resultado: Em qualquer momento dado, apenas os dados de um único arquivo de entrada existem na memória.
Limitação JSON: Para saída JSON (
_write_json_output), o script deve acumular todos os dados para formar um array JSON válido. No entanto, ainda emprega coleta de lixo para descartar artefatos de processamento intermediários assim que são anexados à lista principal.
Coleta de Lixo Explícita: A coleta de lixo automática do Python pode não ser acionada rápido o suficiente ao lidar com loops grandes e apertados de carregamento de dados. Chamadas explícitas de
delcombinadas comgc.collect()são colocadas estrategicamente para garantir que a memória seja liberada de volta para o SO antes de alocar o próximo pedaço.
Funções Principais:
format_dfs(files, config_file, blast_metadata_df): O gerador primário. Determina se um arquivo de resultado pertence a um vírus conhecido (com dataset configurado no YAML) ou é uma execução genérica (nextclade executado com referências informadas pela análise de BLAST). Chama a lógica de processamento apropriada (_process_with_virus_infoou_process_generic_run) e produz o resultado.load_blast_metadata(metadata_path): Carrega os metadados do banco de dados BLAST e normaliza nomes de colunas (ex:accession->virus) para garantir consistência com as saídas do Nextclade.optimize_dataframe_memory(df): Analisa colunas do DataFrame. Se uma coluna de string (comovirus,clade,dataset) tiver uma baixa cardinalidade (número de valores únicos < 50% do total de linhas), converte a coluna para o tipocategory. Isso reduz drasticamente o uso de RAM.add_qualities(df, virus_info): Aplica a lógica de pontuação de qualidade linha por linha. Invoca o auxiliar_compute_metrics_qualitiese então usa as funçõesget_*_qualitypara atribuir notas.add_coverages(df, virus_info): Analisa e formata a stringcdsCoverage. Também calcula a cobertura para regiões alvo específicas e as adiciona como novas colunas (targetRegionsCoverage,targetGeneCoverage).format_sc2_clade(df, dataset_name): Contém lógica específica para SARS-CoV-2. Como o Nextclade emite linhagens Pango em uma coluna específica (Nextclade_pango), esta função mapeia para a colunacladepadrão para consistência.create_unmapped_df(unmapped_sequences, blast_results, blast_metadata_df): Lida com sequências que falharam tanto na identificação do Nextclade quanto no BLAST. Lê o arquivo brutounmapped_sequences.txte cria um DataFrame rotulado como “Unclassified”.write_combined_df(df_iterator, output_file, output_format, ...): O despachante principal. Recebe o geradorformat_dfs(iterador) e o direciona para o backend de escrita apropriado (CSV/TSV ou JSON).
Funções de Controle de Qualidade:
get_genome_quality(scores): Agrega pontuações de métricas individuais em uma Qualidade de Genoma final. Soma as pontuações (A=4, B=3, C=2, D=1) e normaliza para uma escala de 24 pontos para atribuir a nota final.get_target_regions_quality(...): Determina a qualidade de regiões alvo específicas. Lógica: Se o genoma inteiro for A/B, retorna vazio (implícito bom). Caso contrário, calcula a cobertura média das regiões alvo para atribuir uma nota.get_cds_cov_quality(...): Verifica cada CDS contra limites de cobertura para atribuir notas A/B/C/D por gene.get_missing_data_quality(coverage): Pontuado com base em limites (0.9, 0.75, 0.5).get_private_mutations_quality(total, threshold): Pontuado com base no desvio de um limite definido.get_qc_quality(total): Pontuação geral para métricas de contagem (0=A, 1=B, 2=C, >2=D).
extract_target_regions.py
Propósito: Extrai as coordenadas genômicas de regiões de “boa qualidade” para uso posterior (ex: geração de consenso ou design de primers).
Execução: Executado pela regra extract_target_regions após o pós-processamento.
Lógica de Seleção:
A função check_target_regions determina a melhor região para extrair com base na qualidade:
Genoma: Se o
genomeQualitygeral for A ou B, o genoma inteiro é selecionado.Região Alvo: Senão, se
targetRegionsQualityfor A ou B, as regiões alvo específicas são selecionadas.Gene Alvo: Senão, se
targetGeneQualityfor A ou B, o gene alvo é selecionado.
Mapeamento de Coordenadas:
Usa
get_regionspara consultar as coordenadas de início/fim da característica selecionada (gene ou genoma completo) no arquivo GFF.Produz um arquivo BED compatível com
seqtk subseq.