Lesson 2 of 13 · 11 min
Collecting and Curating Your Sequences
A phylogeny is only as good as the sequences that go into it. Use blastp when both your query and the database are protein, and use tblastn to hunt for homologs in nucleotide or genome databases, where the protein query is compared against subjects translated in all six reading frames. Start from one well-annotated query protein and search outward from there.
Searching With BLAST
# query = one reviewed rbcL protein (RuBisCO large subunit)
# -remote runs on NCBI servers, so no local database is needed
blastp \
-query rbcL_query.faa \
-db nr \
-remote \
-evalue 1e-20 \
-max_target_seqs 500 \
-outfmt "6 saccver pident length qcovs evalue bitscore staxids sscinames" \
-out hits.tsvNP_051067.1 99.790 476 100 0.0 972 3702 Arabidopsis thaliana
YP_009179418.1 92.017 476 100 0.0 889 4113 Solanum tuberosum
ABK20720.1 88.235 475 99 0.0 845 161934 Beta vulgaris
AGT21077.1 85.014 474 98 0.0 812 4577 Zea mays
CAA25948.1 74.262 474 96 0.0 708 3055 Chlamydomonas reinhardtii
Not every hit belongs in your dataset. Keep matches with high query coverage and a small e-value, and discard short, partial alignments that will only inject gaps into the tree. Deduplicate the accessions before downloading so you never fetch the same protein twice.
# keep hits with >=90% query coverage (column 4 = qcovs), unique accessions only
awk -F'\t' '$4 >= 90 {print $1}' hits.tsv | sort -u > keep.acc
# download those proteins from Entrez (NCBI EDirect: epost then efetch)
cat keep.acc | epost -db protein | efetch -format fasta > blast_hits.faaCurated Sets From UniProt
# reviewed (Swiss-Prot) rbcL proteins across green plants (Viridiplantae, taxid 33090)
# --data-urlencode lets curl encode the query for you
curl -s -G "https://rest.uniprot.org/uniprotkb/stream" \
--data-urlencode "query=gene:rbcL AND reviewed:true AND taxonomy_id:33090" \
--data "format=fasta" \
-o uniprot_rbcL.faaThe ingroup is the set of taxa whose relationships you want to resolve, so sample it broadly and evenly rather than piling up sequences from one over-studied genus. The outgroup is one or a few sequences that sit just outside the ingroup, and because it roots the tree you need at least one. Aim for even taxon sampling across the ingroup paired with a single, well-placed outgroup.
Tip: Choose an outgroup that is close enough to align cleanly but clearly outside the ingroup. Too close and it may nest inside your tree; too distant and long-branch attraction plus alignment noise will distort the root.
# combine both sources, then curate into a clean multi-FASTA
cat blast_hits.faa uniprot_rbcL.faa > all.faa
# remove exact-duplicate sequences (e.g. the same protein from both sources)
seqkit rmdup -s all.faa > nr.faa
# keep only near-full-length sequences (rbcL is ~475 aa); drop fragments
seqkit seq -m 440 -M 500 nr.faa > sized.faa
# rewrite headers into tree-friendly tips: Genus_species_Accession
# expr 1 = NCBI headers (... [Genus species]); expr 2 = UniProt headers (... OS=Genus species OX=...)
sed -E \
-e 's/^>([^ .]+)[^ ]* .*\[([A-Za-z]+) ([A-Za-z]+).*/>\2_\3_\1/' \
-e 's/^>[a-z]+\|([^|]+)\|[^ ]* .*OS=([A-Za-z]+) ([A-Za-z]+).*/>\2_\3_\1/' \
sized.faa > clean.faa
seqkit stats clean.faaTry it yourself: Pick a protein you know well (for example rbcL, cytochrome b, or elongation factor Tu). Run a remote blastp for it, add three to five reviewed UniProt sequences from your target clade, and choose one outgroup from a sister group. Then dedup and length-filter into a single multi-FASTA and confirm every header is a unique Genus_species_Accession with no spaces or punctuation before you move on to alignment.