-
Notifications
You must be signed in to change notification settings - Fork 0
Distance Matrix Calculator
The Distance Matrix Calculator generates pairwise genetic distance matrices from aligned DNA sequences contained in a FASTA file.
It is intended as a simple educational implementation that provides the first analytical step used by many phylogenetic reconstruction algorithms, including UPGMA.
The calculator currently supports six commonly used distance measures:
| Calculation | Characteristics |
|---|---|
| Hamming distance | Counts the number of differing nucleotide positions |
| Proportional distance (p-distance) | Reports the proportion of differing positions |
| Jukes–Cantor (JC69) | Applies a substitution correction to estimate the true evolutionary distance while accounting for multiple mutations at the same site |
| Kimura two-parameter (K80) | Distinguishes transitions from transversions when correcting observed divergence |
| Felsenstein 1981 (F81) | Allows unequal nucleotide frequencies when estimating corrected evolutionary distance |
| Hasegawa-Kishino-Yano (HKY85) | Combines unequal nucleotide frequencies with transition/transversion bias |
Together these provide a progression from simple sequence comparison through to model-based estimates of evolutionary divergence.
Results are written in both JSON and CSV formats for use by downstream tools or for inspection in spreadsheet software.
Unlike the molecular clock simulators, the Distance Matrix Calculator performs no evolutionary simulation. Instead, it analyses existing sequence data to quantify the genetic differences between every pair of taxa.
The calculator begins by reading an aligned FASTA file supplied on the command line. Each FASTA record becomes a taxon within the analysis.
The current implementation assumes that all sequences:
- Are aligned
- Are the same length
- Contain comparable nucleotide positions
If these conditions are not satisfied, the calculator reports an error.
Every sequence is compared with every other sequence. For each pair of taxa, the calculator examines every nucleotide position in turn.
Each position is classified as either identical or different and the total number of differing positions forms the basis of the selected distance measure.
Because genetic distance is symmetric, the calculator computes only one comparison for each pair and mirrors the result across the distance matrix.
The distance between a sequence and itself is always zero.
The Hamming distance is the simplest supported metric. It is defined as the number of nucleotide positions at which two aligned sequences differ.
For example:
Sequence A: ACTGAC
Sequence B: ACTAAC
Only one nucleotide differs, giving a Hamming distance of 1.
Hamming distance is an absolute measure of sequence difference and is most useful when all sequences are the same length.
The proportional distance (often called p-distance) normalises the Hamming distance by sequence length. It is calculated as:
proportional_distance = differing_positions / sequence_length
For example, if two sequences differ at 12 positions within a sequence of length 500:
p-distance = 12 / 500 = 0.024
This represents a 2.4% observed sequence divergence.
Unlike Hamming distance, proportional distance produces values between 0 and 1, making comparisons easier across datasets with different sequence lengths.
The proportional distance is also the simplest estimate of evolutionary divergence and is commonly used as the starting point for introductory phylogenetic algorithms.
The Jukes–Cantor (1969) model extends the proportional distance by accounting for substitutions that are no longer directly observable.
Over long periods of evolutionary time, a nucleotide position may mutate more than once. Simply counting the observed differences therefore underestimates the true number of substitution events that have occurred.
The Jukes–Cantor model assumes:
- Equal frequencies of the four nucleotides
- Equal probability of every possible nucleotide substitution
- A constant substitution rate across all sites
Using these assumptions, the corrected evolutionary distance is calculated as:
d = -3/4 × ln(1 - 4p/3)
where:
- p is the proportional distance
- d is the estimated substitutions per site
For small values of p, the corrected distance is very similar to the proportional distance.
As sequence divergence increases, however, the Jukes–Cantor correction becomes progressively larger because it compensates for substitutions that are hidden by multiple mutation events at the same nucleotide position.
The Jukes–Cantor model is only defined when:
p < 0.75
As the observed proportion of differing sites approaches 75%, sequence information becomes saturated and it is no longer possible to estimate evolutionary distance reliably using this model.
When saturation is reached, the calculator reports an infinite evolutionary distance.
The Kimura two-parameter model extends model-based correction by distinguishing between two classes of nucleotide substitution.
- Transitions are substitutions within the same nucleotide class: A ↔ G and C ↔ T.
- Transversions are substitutions between nucleotide classes: all other A, C, G and T changes.
Transitions often occur more frequently than transversions in real sequence evolution. K80 keeps the simple equal-base-frequency assumptions of JC69, but estimates distance from separate transition and transversion proportions.
For two aligned DNA sequences, the calculator counts:
P = transitions / sequence_length
Q = transversions / sequence_length
The corrected evolutionary distance is:
d = -1/2 × ln(1 - 2P - Q) - 1/4 × ln(1 - 2Q)
where:
- P is the observed transition proportion
- Q is the observed transversion proportion
- d is the estimated substitutions per site
The model is only defined when both logarithm arguments are positive:
1 - 2P - Q > 0
1 - 2Q > 0
If either term is zero or negative, the calculator reports an infinite evolutionary distance because the observed divergence is too saturated for the K80 correction to estimate a finite value.
The Felsenstein 1981 model extends JC69 by allowing unequal equilibrium nucleotide frequencies.
Like JC69, F81 treats every substitution type as having the same underlying rate. Unlike JC69, it estimates the frequencies of A, C, G and T from each pairwise sequence comparison and uses those empirical frequencies in the correction.
For two aligned DNA sequences, the calculator first estimates:
piA, piC, piG, piT
from the bases pooled across both sequences. It then calculates:
B = 1 - (piA^2 + piC^2 + piG^2 + piT^2)
The corrected evolutionary distance is:
d = -B x ln(1 - p/B)
where:
- p is the proportional distance
- B is the unequal-frequency correction factor
- d is the estimated substitutions per site
When all four nucleotide frequencies are equal, B is 0.75 and the F81 equation becomes equivalent to the Jukes-Cantor correction.
The model is only defined when:
p < B
If the logarithm term is zero or negative, the calculator reports an infinite evolutionary distance because the observed divergence is too saturated for the F81 correction to estimate a finite value.
The Hasegawa-Kishino-Yano 1985 model combines the two biological refinements introduced by K80 and F81.
Like K80, HKY85 distinguishes between transitions and transversions. Like F81, it estimates empirical nucleotide frequencies from the pairwise sequence comparison rather than assuming that A, C, G and T are equally common.
For two aligned DNA sequences, the calculator counts:
P = transitions / sequence_length
Q = transversions / sequence_length
It also estimates:
piA, piC, piG, piT
from the bases pooled across both sequences. These frequencies are combined into the purine and pyrimidine frequency factor:
B = 2 x (piA + piG) x (piC + piT)
The corrected evolutionary distance is:
d = -B x ln(1 - P/B - Q) - 1/2 x (1 - B) x ln(1 - 2Q)
where:
- P is the observed transition proportion
- Q is the observed transversion proportion
- B is the unequal-frequency correction factor
- d is the estimated substitutions per site
When the purine and pyrimidine frequencies are balanced, B is 0.5 and the equation becomes equivalent to the Kimura two-parameter correction.
The model is only defined when both logarithm arguments are positive:
1 - P/B - Q > 0
1 - 2Q > 0
If either term is zero or negative, the calculator reports an infinite evolutionary distance because the observed divergence is too saturated for the HKY85 correction to estimate a finite value.
The distances calculated directly from a sequence alignment (such as Hamming or proportional distance) represent the observed differences between sequences, not necessarily the true amount of evolutionary change. Over time, a single nucleotide position may undergo multiple substitutions. For example, a site might change from A → G → A, leaving no observable difference despite two mutations having occurred, or A → G → T, where two substitutions are observed as a single difference. As sequences diverge, these “hidden” substitutions become increasingly common, causing simple observed distances to underestimate the true evolutionary distance.
Substitution models address this by applying a mathematical model of sequence evolution to the observed distances. Each model makes a different set of biological assumptions—for example, that all substitutions are equally likely and base frequencies are equal (JC69), that transitions occur more frequently than transversions (K80), that nucleotide frequencies differ (F81), or that both transition bias and unequal nucleotide frequencies apply together (HKY85). These assumptions lead to equations that estimate the expected number of substitutions per site, producing a distance matrix that more closely reflects the underlying evolutionary history. This corrected distance matrix can then be used as the input to phylogenetic reconstruction algorithms such as UPGMA or Neighbour Joining.
The calculated distances are stored in a square matrix with rows and columns representing taxa. Each cell contains the genetic distance between the corresponding pair of sequences.
For example:
| Taxon A | Taxon B | Taxon C | |
|---|---|---|---|
| Taxon A | 0 | 2 | 5 |
| Taxon B | 2 | 0 | 4 |
| Taxon C | 5 | 4 | 0 |
The diagonal always contains zero because every sequence is identical to itself.
The matrix is symmetric because the distance from A to B is identical to the distance from B to A.
The calculator writes the completed distance matrix in two formats.
| Format | Description |
|---|---|
| CSV | Tabular representation suitable for spreadsheets and external tools |
| JSON | Structured representation suitable for downstream Python modules |
Providing both formats allows the matrix to be inspected manually while remaining easy to consume programmatically.
The Distance Matrix Calculator deliberately focuses on clarity rather than biological complexity.
The supported distance measures form a natural progression:
- Hamming distance measures the absolute number of differing nucleotide positions
- Proportional distance normalises this by sequence length to estimate observed divergence
- Jukes–Cantor applies a simple evolutionary model to estimate the true number of substitutions per site
- Kimura two-parameter separates transitions from transversions before applying a correction
- Felsenstein 1981 allows unequal nucleotide frequencies while retaining equal substitution rates
- Hasegawa-Kishino-Yano 1985 combines transition/transversion bias with unequal nucleotide frequencies
The calculator is implemented as a reusable Python module with a lightweight command-line interface, allowing the same distance calculations to be reused directly by future phylogenetic reconstruction algorithms such as UPGMA.
Future releases may introduce more sophisticated substitution models, including TN93 and General Time Reversible (GTR).
First create and activate a virtual environment:
python -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install -e .These commands are correct for macOS/Linux but may require modification for Windows.
The calculator can then be run as follows:
python -m distancematrix --input "/path/to/sequences.fasta" --output "/path/to/output/folder"Optionally, the --distance-type argument selects the distance calculation to perform.
Supported values are:
| Distance Type | Description |
|---|---|
| hamming | Counts the number of differing nucleotide positions |
| proportional | Reports the proportion of differing positions |
| jc69 | Applies the Jukes–Cantor substitution correction |
| k80 | Applies the Kimura two-parameter correction |
| f81 | Applies the Felsenstein 1981 correction |
| hky85 | Applies the Hasegawa-Kishino-Yano correction |
If omitted, hamming is used by default.