Lesson 11 of 13 · 10 min
Genome Annotation: Genes and Variant Effects
A newly sequenced genome is just a very long string of the letters A, C, G, and T, with nothing marking what any stretch actually means. Genome annotation adds that missing layer of meaning, and it breaks into two linked tasks that this lesson walks through.
Structural And Functional
Structural annotation locates features on the sequence, such as a gene (a stretch of DNA carrying the instructions for a product) and its exons (the pieces that stay in the final messenger RNA after the in-between introns are cut out). Functional annotation then labels what each feature does, for example that a gene encodes an oxygen-carrying protein. You always do structural annotation first, because you cannot describe a feature you have not yet found.
Gene Models In GFF3
Annotations are stored in plain-text feature tables, most often in the GFF3 format or the closely related GTF format. Each line describes one feature using nine tab-separated columns: the sequence name, the source, the feature type, the start and end positions, a score, the strand, a phase, and a final column of attributes. Features are nested into a gene model, where a gene contains one or more transcripts (mRNA), and each transcript contains exons and coding sequences (CDS).
##gff-version 3
chr1 Ensembl gene 1000 9000 . + . ID=gene:ENSG01;Name=HBB
chr1 Ensembl mRNA 1000 9000 . + . ID=tx:ENST01;Parent=gene:ENSG01
chr1 Ensembl exon 1000 1200 . + . Parent=tx:ENST01
chr1 Ensembl exon 7000 9000 . + . Parent=tx:ENST01
chr1 Ensembl CDS 1050 1200 . + 0 Parent=tx:ENST01Variant Effect Prediction
Once genes are annotated, you can ask what a genetic variant does to them. Tools like Ensembl VEP (Variant Effect Predictor) and SnpEff read a list of variants and compare each one against the gene models to predict its consequence. Common consequences include a synonymous_variant (the DNA changes but the protein stays the same), a missense_variant (one amino acid is swapped for another), and a stop_gained variant (a change creates an early stop codon that cuts the protein short).
The command below runs VEP on an input VCF file, the standard text format that lists variant positions and their alleles, and writes the annotated results to an output file. The --cache and --offline flags tell VEP to use a pre-downloaded local database instead of querying the internet, while --species homo_sapiens picks the human gene set to compare against. The --tab flag asks for tab-separated output, and --symbol adds the human-readable gene name to each result. VEP's real output carries more columns than are shown below, but these few are enough to read off each variant's effect.
vep --input_file variants.vcf --output_file variants.vep.txt --species homo_sapiens --cache --offline --tab --symbol#Uploaded_variation Location Allele Gene SYMBOL Consequence Amino_acids Codons
var1 7:140753336 T ENSG00000157764 BRAF missense_variant V/E gTg/gAg
var2 11:5226774 T ENSG00000244734 HBB synonymous_variant L ctG/ctA
var3 17:7673776 A ENSG00000141510 TP53 stop_gained Q/* Cag/Tag
Try it yourself: Download a small GFF3 file, for example a single chromosome from the Ensembl FTP site, and run this one line: grep -v "^#" your_file.gff3 | cut -f3 | sort | uniq -c. Here grep -v "^#" removes the comment lines that start with a hash, cut -f3 keeps only the third column (the feature type), and sort | uniq -c groups identical types together and counts them, giving you an instant structural-annotation summary of the file.