Skip to contents

Introduction

Kamil Slowikowski

2024-06-05

The IMGTHLA provides a Github repo with alignments of amino acid sequences and nucleotide sequences for thousands of alleles of the HLA genes. The IMGTHLA alignments define the official numbering scheme, and they provide some explanations for the conventions on their help page.

The hlabud R package provides easy access to the alignment data, and hlabud follows the official numbering scheme. The examples below should help beginners to visualize and understand how the conventions work.

Alignment files on the IMGTHLA Github page

The IMGTHLA Github page provides a folder with alignment files.

For the examples in this vignette, we will use the HLA-DRB1 gene.

For DRB1, we can find three separate files:

The files contain different information:

  • gen contains genomic DNA sequences.
  • nuc contains nucleotide coding sequences (CDS).
  • prot contains protein sequences (amino acids).

Let’s consider the DRB1_prot.txt file. What does the file look like?

It is a plain text file with a header and sequence alignments. In the alignment, each line represents one sequence (or allele), and each line has 100 residues. The first 100 residues for all alleles are shown in the first block. Then, the next block has the next 100 residues for all of the alleles, and so on.

Numbering conventions

Here are the conventions used for alignments (copied from EBI):

  • The entry for each allele is displayed in respect to the reference sequences.
  • Where identity to the reference sequence is present the base will be displayed as a hyphen (-).
  • Non-identity to the reference sequence is shown by displaying the appropriate base at that position.
  • Where an insertion or deletion has occurred this will be represented by a period (.).
  • If the sequence is unknown at any point in the alignment, this will be represented by an asterisk (*).
  • In protein alignments for null alleles, the ‘Stop’ codons will be represented by a hash (X).
  • In protein alignments, sequence following the termination codon, will not be marked and will appear blank.
  • These conventions are used for both nucleotide and protein alignments.

That’s a lot of information! Let’s try to work through an example to illustrate how this works.

The first sequence in the alignment is the reference sequence. The position numbering is relative to the reference sequence. That means deletions (.) in the reference sequence are not numbered.

Notice below that the numbering starts with negative numbers. The help page clarifies:

Protein Sequence Numbering

  • For amino acid-based systems, the start codon of the mature protein is labeled codon 1.
  • The codon 5’ to this is numbered -1.
  • All numbering is based on the reference sequence.

There is no amino acid with the number 0.

Numbering indels

The alignment below shows that 100 residues are displayed in chunks of 10:

The numbering convention says that indels in the reference sequence are not numbered.

To clarify this point, I manually added additional numbers (11, 21, 30, 39, 49, 59) to the alignment below:

Notice that when we move from the first chunk GDTRPRFLWQ to the next chunk LKFECHFFNG we simply add 10 to 1 to get 11 for the number of the L amino acid. Then, as we move on to TERVR.LLER, we add 10 to 11 to get 21 for the T amino acid.

However, as we move on to CIYNQEE.SV the rule of “add 10” does not work. Instead of labeling C as position 31, we label it position 30. Why?

The reason why C is 30, and not 31, is because there is an indel (or gap) in the reference sequence at position 25_26 (notice the . in R.L). The convention is that deletions in the reference sequence are not numbered.

Let’s take a closer look at this data with hlabud.

Here are the first few amino acid positions for the first 4 sequences:

library(hlabud)
a <- hla_alignments("DRB1", release = "3.56.0")
seqs <- substr(a$sequences[1:4], 30, 89)
str_replace_all(seqs, "(\\S{10})", "\\1 ")
#> [1] "GDTRPRFLWQ LKFECHFFNG TERVR.LLER CIYNQEE.SV RFDSDVGEYR AVTELGRPDA "
#> [2] "---------- ---------- -----.---- -------.-- ---------- ---------- "
#> [3] "---------- ---------- -----.---- -------.-- ---------- ---------- "
#> [4] "---------- ---------- -----.---- -------.-- ---------- ---------- "

This is how hlabud numbers the positions that we are focusing on in this example:

colnames(a$alleles)[50:70]
#>  [1] "21"    "22"    "23"    "24"    "25"    "25_26" "26"    "27"    "28"   
#> [10] "29"    "30"    "31"    "32"    "33"    "34"    "35"    "36"    "36_37"
#> [19] "37"    "38"    "39"

If hlabud is using the correct numbering, then we should see:

  • T at position 21
  • C at position 30
a$alleles[1,"21"]
#> [1] "T"
a$alleles[1,"30"]
#> [1] "C"

What do we see at positions 25, 26, and 25_26?

Here is the alignment file:

And here is the result from hlabud:

a$alleles[1,"25"]
#> [1] "R"
a$alleles[1,"26"]
#> [1] "L"
a$alleles[1,"25_26"]
#> [1] "."

So, we can see that the deletion between positions 25 and 26 is not numbered like the other residues. Instead, it gets a special label (25_26) that consists of the positions flanking the indel (25 and 26).

What alleles do we observe at position 25_26?

table(a$alleles[,"25_26"])
#> 
#>    .    *    W 
#> 3658   12    1

There are three possibilities at position 25_26:

  • . indicates a deletion of 1 amino acid (or the absence of an amino at this position)
  • * indicates that the sequence is unknown at this position
  • W indicates tryptophan at this position

I hope this example helps to explain the numbering of indels.

If you notice any discrepancy between hlabud and IMGT, please report it.