O que filogenética faz?
Visão Geral
A análise filogenética reconstrói a história evolutiva de sequências biológicas (genes, proteínas, genomas) inferindo o padrão de ramificação da descendência. Esta habilidade cobre o pipeline padrão:
- MAFFT — Alinhamento múltiplo de sequências
- IQ-TREE 2 — Inferência de árvore por máxima verossimilhança com seleção de modelo
- FastTree — Máxima verossimilhança aproximada rápida (para grandes conjuntos de dados)
- ETE3 — Biblioteca Python para manipulação e visualização de árvores
Instalação:
# Conda (recomendado para ferramentas CLI)
conda install -c bioconda mafft iqtree fasttree
uv pip install ete3
# A renderização TreeStyle/NodeStyle do ete3 depende do backend Qt, portanto a saída de imagem
# precisa do PyQt5; a análise e estatísticas de árvores funcionam sem ele.
uv pip install PyQt5
Quando Usar Esta Habilidade
Use filogenética quando:
- Relações evolutivas: Qual organismo/gene é mais proximamente relacionado à minha sequência?
- Filodinâmica viral: Rastreie a propagação de surtos e estime datas de transmissão
- Análise de famílias proteicas: Infira relações evolutivas dentro de uma família de genes
- Detecção de transferência horizontal de genes: Identifique genes com árvores de espécies/genes discordantes
- Reconstrução de sequências ancestrais: Infira sequências proteicas ancestrais
- Análise de relógio molecular: Estime datas de divergência usando amostragem temporal
- Acompanhante de GWAS: Coloque variantes em contexto evolutivo (ex: variantes SARS-CoV-2)
- Microbiologia: Filogenia de espécies a partir de rRNA 16S ou filogenia do genoma central
Fluxo de Trabalho Padrão
1. Alinhamento Múltiplo de Sequências com MAFFT
import subprocess
import os
def run_mafft(input_fasta: str, output_fasta: str, method: str = "auto",
n_threads: int = 4) -> str:
"""
Alinha sequências com MAFFT.
Args:
input_fasta: Caminho para o arquivo FASTA não alinhado
output_fasta: Caminho para a saída alinhada
method: 'auto' (seleção automática), 'einsi' (preciso), 'linsi' (preciso, lento),
'fftnsi' (médio), 'fftns' (rápido), 'retree2' (rápido)
n_threads: Número de threads da CPU
Returns:
Caminho para o arquivo FASTA alinhado
"""
methods = {
"auto": ["mafft", "--auto"],
"einsi": ["mafft", "--genafpair", "--maxiterate", "1000"],
"linsi": ["mafft", "--localpair", "--maxiterate", "1000"],
"fftnsi": ["mafft", "--fftnsi"],
"fftns": ["mafft", "--fftns"],
"retree2": ["mafft", "--retree", "2"],
}
cmd = methods.get(method, methods["auto"])
cmd += ["--thread", str(n_threads), "--inputorder", input_fasta]
with open(output_fasta, 'w') as out:
result = subprocess.run(cmd, stdout=out, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
raise RuntimeError(f"MAFFT falhou:\n{result.stderr}")
# Contar sequências alinhadas
with open(output_fasta) as f:
n_seqs = sum(1 for line in f if line.startswith('>'))
print(f"MAFFT: {n_seqs} sequências alinhadas → {output_fasta}")
return output_fasta
# Guia de seleção de método MAFFT:
# Poucas sequências (<200), preciso: linsi ou einsi
# Muitas sequências (<1000), moderado: fftnsi
# Grandes conjuntos de dados (>1000): fftns ou auto
# Ultra-rápido (>10000): mafft --retree 1
2. Aparar Alinhamento (Opcional, mas Recomendado)
def trim_alignment_trimal(aligned_fasta: str, output_fasta: str,
method: str = "automated1") -> str:
"""
Apara colunas mal alinhadas com TrimAl.
Métodos:
- 'automated1': Heurística automática (recomendado)
- 'gappyout': Remove colunas com gaps
- 'strict': Limiar estrito de gaps
"""
cmd = ["trimal", f"-{method}", "-in", aligned_fasta, "-out", output_fasta, "-fasta"]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Aviso TrimAl: {result.stderr}")
# Voltar para o alinhamento não aparado
import shutil
shutil.copy(aligned_fasta, output_fasta)
return output_fasta
3. IQ-TREE 2 — Árvore de Máxima Verossimilhança
def run_iqtree(aligned_fasta: str, output_prefix: str,
model: str = "TEST", bootstrap: int = 1000,
n_threads: int = 4, extra_args: list = None) -> dict:
"""
Constrói uma árvore de máxima verossimilhança com IQ-TREE 2.
Args:
aligned_fasta: Arquivo FASTA alinhado
output_prefix: Prefixo para os arquivos de saída
model: 'TEST' para seleção automática de modelo, ou especifique (ex: 'GTR+G' para DNA,
'LG+G4' para proteínas, 'JTT+G' para proteínas)
bootstrap: Número de réplicas de bootstrap ultrafast (1000 recomendado)
n_threads: Número de threads ('AUTO' para detecção automática)
extra_args: Argumentos adicionais do IQ-TREE
Returns:
Dicionário com caminhos para os arquivos de saída
"""
cmd = [
"iqtree2",
"-s", aligned_fasta,
"--prefix", output_prefix,
"-m", model,
"-B", str(bootstrap), # Bootstrap ultrafast
"-T", str(n_threads),
"--redo" # Sobrescrever resultados existentes
]
if extra_args:
cmd.extend(extra_args)
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"IQ-TREE falhou:\n{result.stderr}")
# Imprimir resultado da seleção de modelo
log_file = f"{output_prefix}.log"
if os.path.exists(log_file):
with open(log_file) as f:
for line in f:
if "Best-fit model" in line:
print(f"IQ-TREE: {line.strip()}")
output_files = {
"tree": f"{output_prefix}.treefile",
"log": f"{output_prefix}.log",
"iqtree": f"{output_prefix}.iqtree", # Relatório completo
"model": f"{output_prefix}.model.gz",
}
print(f"IQ-TREE: Árvore salva em {output_files['tree']}")
return output_files
# Guia de seleção de modelo IQ-TREE:
# DNA: TEST → GTR+G, HKY+G, TrN+G
# Proteína: TEST → LG+G4, WAG+G, JTT+G, Q.pfam+G
# Códon: TEST → MG+F3X4
# Para análise temporal (relógio molecular), adicione:
# extra_args = ["--date", "dates.txt", "--clock-test", "--date-CI", "95"]
4. FastTree — ML Aproximado Rápido
Para grandes conjuntos de dados (>1000 sequências) onde o IQ-TREE é muito lento:
def run_fasttree(aligned_fasta: str, output_tree: str,
sequence_type: str = "nt", model: str = "gtr",
n_threads: int = 4) -> str:
"""
Constrói uma árvore ML aproximada rápida com FastTree.
Args:
sequence_type: 'nt' para nucleotídeo ou 'aa' para aminoácido
model: Para nt: 'gtr' (recomendado) ou 'jc'; para aa: 'lg', 'wag', 'jtt'
"""
if sequence_type == "nt":
cmd = ["FastTree", "-nt", "-gtr"]
else:
cmd = ["FastTree", f"-{model}"]
cmd += [aligned_fasta]
with open(output_tree, 'w') as out:
result = subprocess.run(cmd, stdout=out, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
raise RuntimeError(f"FastTree falhou:\n{result.stderr}")
print(f"FastTree: Árvore salva em {output_tree}")
return output_tree
5. Análise e Visualização de Árvores com ETE3
from ete3 import Tree, TreeStyle, NodeStyle, TextFace, PhyloTree
import matplotlib.pyplot as plt
def load_tree(tree_file: str) -> Tree:
"""Carrega um arquivo de árvore Newick."""
t = Tree(tree_file)
print(f"Árvore: {len(t)} folhas, {len(list(t.traverse()))} nós")
return t
def basic_tree_stats(t: Tree) -> dict:
"""Calcula estatísticas básicas da árvore."""
leaves = t.get_leaves()
distances = [t.get_distance(l1, l2) for l1 in leaves[:min(50, len(leaves))]
for l2 in leaves[:min(50, len(leaves))] if l1 != l2]
stats = {
"n_leaves": len(leaves),
"n_internal_nodes": len(t) - len(leaves),
"total_branch_length": sum(n.dist for n in t.traverse()),
"max_leaf_distance": max(distances) if distances else 0,
"mean_leaf_distance": sum(distances)/len(distances) if distances else 0,
}
return stats
def find_mrca(t: Tree, leaf_names: list) -> Tree:
"""Encontra o ancestral comum mais recente de um conjunto de folhas."""
return t.get_common_ancestor(*leaf_names)
def visualize_tree(t: Tree, output_file: str = "tree.png",
show_branch_support: bool = True,
color_groups: dict = None,
width: int = 800) -> None:
"""
Renderiza árvore filogenética para imagem.
Args:
t: Objeto Tree do ETE3
color_groups: Dicionário mapeando leaf_name → color (para colorir táxons)
show_branch_support: Mostrar valores de bootstrap
"""
ts = TreeStyle()
ts.show_leaf_name = True
ts.show_branch_support = show_branch_support
ts.mode = "r" # 'r' = retangular, 'c' = circular
if color_groups:
for node in t.traverse():
if node.is_leaf() and node.name in color_groups:
nstyle = NodeStyle()
nstyle["fgcolor"] = color_groups[node.name]
nstyle["size"] = 8
node.set_style(nstyle)
t.render(output_file, tree_style=ts, w=width, units="px")
print(f"Árvore salva em: {output_file}")
def midpoint_root(t: Tree) -> Tree:
"""Enraíza a árvore no ponto médio (use quando o grupo externo for desconhecido)."""
t.set_outgroup(t.get_midpoint_outgroup())
return t
def prune_tree(t: Tree, keep_leaves: list) -> Tree:
"""Poda a árvore para manter apenas as folhas especificadas."""
t.prune(keep_leaves, preserve_branch_length=True)
return t
6. Script de Análise Completo
import subprocess, os
from ete3 import Tree
def full_phylogenetic_analysis(
input_fasta: str,
output_dir: str = "phylo_results",
sequence_type: str = "nt",
n_threads: int = 4,
bootstrap: int = 1000,
use_fasttree: bool = False
) -> dict:
"""
Pipeline filogenético completo: alinhar → aparar → árvore → visualizar.
Args:
input_fasta: FASTA não alinhado
sequence_type: 'nt' (nucleotídeo) ou 'aa' (aminoácido/proteína)
use_fasttree: Usar FastTree em vez de IQ-TREE (mais rápido para grandes conjuntos de dados)
"""
os.makedirs(output_dir, exist_ok=True)
prefix = os.path.join(output_dir, "phylo")
print("=" * 50)
print("Etapa 1: Alinhamento Múltiplo de Sequências (MAFFT)")
aligned = run_mafft(input_fasta, f"{prefix}_aligned.fasta",
method="auto", n_threads=n_threads)
print("\nEtapa 2: Inferência de Árvore")
if use_fasttree:
tree_file = run_fasttree(
aligned, f"{prefix}.tree",
sequence_type=sequence_type,
model="gtr" if sequence_type == "nt" else "lg"
)
else:
model = "TEST" if sequence_type == "nt" else "TEST"
iqtree_files = run_iqtree(
aligned, prefix,
model=model,
bootstrap=bootstrap,
n_threads=n_threads
)
tree_file = iqtree_files["tree"]
print("\nEtapa 3: Análise da Árvore")
t = Tree(tree_file)
t = midpoint_root(t)
stats = basic_tree_stats(t)
print(f"Estatísticas da árvore: {stats}")
print("\nEtapa 4: Visualização")
visualize_tree(t, f"{prefix}_tree.png", show_branch_support=True)
# Salvar árvore enraizada
rooted_tree_file = f"{prefix}_rooted.nwk"
t.write(format=1, outfile=rooted_tree_file)
results = {
"aligned_fasta": aligned,
"tree_file": tree_file,
"rooted_tree": rooted_tree_file,
"visualization": f"{prefix}_tree.png",
"stats": stats
}
print("\n" + "=" * 50)
print("Análise filogenética concluída!")
print(f"Resultados em: {output_dir}/")
return results
Guia de Modelos IQ-TREE
Modelos de DNA
| Modelo | Descrição | Caso de uso |
|---|---|---|
GTR+G4 | General Time Reversible + Gama | Modelo de DNA mais flexível |
HKY+G4 | Hasegawa-Kishino-Yano + Gama | Modelo de duas taxas (comum) |
TrN+G4 | Tamura-Nei | Transições desiguais |
JC | Jukes-Cantor | Mais simples; todas as taxas iguais |
Modelos de Proteína
| Modelo | Descrição | Caso de uso |
|---|---|---|
LG+G4 | Le-Gascuel + Gama | Melhor modelo médio de proteína |
WAG+G4 | Whelan-Goldman | Amplamente usado |
JTT+G4 | Jones-Taylor-Thornton | Modelo clássico |
Q.pfam+G4 | Treinado em Pfam | Para famílias proteicas similares a Pfam |
Q.bird+G4 | Específico para aves | Proteínas de vertebrados |
Dica: Use -m TEST para que o IQ-TREE selecione automaticamente o melhor modelo.
Melhores Práticas
- Qualidade do alinhamento primeiro: Alinhamento ruim → árvores não confiáveis; verifique o alinhamento manualmente
- Use
linsipara alinhamentos pequenos (<200 seq),fftnsouautopara grandes - Seleção de modelo: Sempre use
-m TESTpara IQ-TREE, a menos que tenha um motivo específico - Bootstrap: Use ≥1000 bootstraps ultrafast (
-B 1000) para suporte de ramos - Enraíze a árvore: Árvores não enraizadas podem ser enganosas; use grupo externo ou enraizamento no ponto médio
- FastTree para >5000 sequências: IQ-TREE fica lento; FastTree é 10–100× mais rápido
- Aparar alinhamentos longos: TrimAl remove colunas não confiáveis; melhora a precisão da árvore
- Verifique recombinação em sequências virais/bacterianas antes de construir árvores (
RDP4,GARD)
Recursos Adicionais
- MAFFT: https://mafft.cbrc.jp/alignment/software/
- IQ-TREE 2: http://www.iqtree.org/ | Tutorial: https://www.iqtree.org/workshop/molevol2022
- FastTree: http://www.microbesonline.org/fasttree/
- ETE3: http://etetoolkit.org/
- FigTree (visualização GUI): https://tree.bio.ed.ac.uk/software/figtree/
- iTOL (visualização web): https://itol.embl.de/
- MUSCLE (alinhador alternativo): https://www.drive5.com/muscle/
- TrimAl (aparamento de alinhamento): https://vicfero.github.io/trimal/