← Files Biological Sequence & Alignment ViewerARCHIVED FILE
src/sequence/genetic-code.ts
6.29 KB · Sep 30, 2026 · 23:01 UTC
import { expandNucleotideSymbol } from "../nucleotide-alphabet";
const CODON_ORDER = "TCAG";
export type GeneticCode = {
id: number;
name: string;
startCodons: ReadonlySet<string>;
table: Readonly<Record<string, string>>;
};
type GeneticCodeDefinition = {
aminoAcids: string;
name: string;
startCodons: ReadonlyArray<string>;
};
// NCBI translation tables in the canonical T/C/A/G base order. This is the
// single translation source used by CDS, six-frame, and ORF workflows.
const GENETIC_CODE_DEFINITIONS: Readonly<
Record<number, GeneticCodeDefinition>
> = Object.freeze({
1: definition("Standard", ["ATG", "CTG", "TTG"], "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
2: definition("Vertebrate Mitochondrial", ["ATA", "ATC", "ATG", "ATT", "GTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG"),
3: definition("Yeast Mitochondrial", ["ATA", "ATG", "GTG"], "FFLLSSSSYY**CCWWTTTTPPPPHHQQRRRRIIMMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
4: definition("Mold, Protozoan, and Coelenterate Mitochondrial", ["ATA", "ATC", "ATG", "ATT", "CTG", "GTG", "TTA", "TTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
5: definition("Invertebrate Mitochondrial", ["ATA", "ATC", "ATG", "ATT", "GTG", "TTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSSSVVVVAAAADDEEGGGG"),
6: definition("Ciliate, Dasycladacean, and Hexamita Nuclear", ["ATG"], "FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
9: definition("Echinoderm and Flatworm Mitochondrial", ["ATG", "GTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG"),
10: definition("Euplotid Nuclear", ["ATG"], "FFLLSSSSYY**CCCWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
11: definition("Bacterial, Archaeal, and Plant Plastid", ["ATA", "ATC", "ATG", "ATT", "CTG", "GTG", "TTG"], "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
12: definition("Alternative Yeast Nuclear", ["ATG", "CTG"], "FFLLSSSSYY**CC*WLLLSPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
13: definition("Ascidian Mitochondrial", ["ATA", "ATG", "GTG", "TTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG"),
14: definition("Alternative Flatworm Mitochondrial", ["ATG"], "FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG"),
15: definition("Blepharisma Macronuclear", ["ATG"], "FFLLSSSSYY*QCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
16: definition("Chlorophycean Mitochondrial", ["ATG"], "FFLLSSSSYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
21: definition("Trematode Mitochondrial", ["ATG", "GTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNNKSSSSVVVVAAAADDEEGGGG"),
22: definition("Scenedesmus obliquus Mitochondrial", ["ATG"], "FFLLSS*SYY*LCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
23: definition("Thraustochytrium Mitochondrial", ["ATG", "ATT", "GTG"], "FF*LSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
24: definition("Pterobranchia Mitochondrial", ["ATG", "CTG", "GTG", "TTG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSSKVVVVAAAADDEEGGGG"),
25: definition("Candidate Division SR1 and Gracilibacteria", ["ATG", "GTG", "TTG"], "FFLLSSSSYY**CCGWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
26: definition("Pachysolen tannophilus Nuclear", ["ATG", "CTG"], "FFLLSSSSYY**CC*WLLLAPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
27: definition("Karyorelict Nuclear", ["ATG"], "FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
28: definition("Condylostoma Nuclear", ["ATG"], "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
29: definition("Mesodinium Nuclear", ["ATG"], "FFLLSSSSYYYYCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
30: definition("Peritrich Nuclear", ["ATG"], "FFLLSSSSYYEECC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
31: definition("Blastocrithidia Nuclear", ["ATG"], "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
32: definition("Balanophoraceae Plastid", ["ATA", "ATC", "ATG", "ATT", "CTG", "GTG", "TTG"], "FFLLSSSSYY*WCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"),
33: definition("Cephalodiscidae Mitochondrial", ["ATG", "CTG", "GTG", "TTG"], "FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSSKVVVVAAAADDEEGGGG"),
});
const GENETIC_CODES = new Map<number, GeneticCode>(
Object.entries(GENETIC_CODE_DEFINITIONS).map(([rawId, value]) => {
const id = Number(rawId);
return [id, { id, name: value.name, startCodons: new Set(value.startCodons), table: createCodonTable(value.aminoAcids) }];
}),
);
export const SUPPORTED_GENETIC_CODE_IDS = Object.freeze(
[...GENETIC_CODES.keys()].sort((left, right) => left - right),
);
export function getGeneticCode(id = 1): GeneticCode | null {
return GENETIC_CODES.get(id) ?? null;
}
export function translateGeneticCodeCodon(
codon: string,
geneticCodeId = 1,
isInitiator = false,
): string {
const code = getGeneticCode(geneticCodeId);
if (code == null) return "X";
const possibilities = expandCodon(codon.toUpperCase().replaceAll("U", "T"));
if (possibilities.length === 0) return "X";
if (isInitiator && possibilities.every((candidate) => code.startCodons.has(candidate))) return "M";
const residues = new Set(possibilities.map((candidate) => code.table[candidate] ?? "X"));
return residues.size === 1 ? [...residues][0] ?? "X" : "X";
}
function definition(name: string, startCodons: ReadonlyArray<string>, aminoAcids: string): GeneticCodeDefinition {
return { aminoAcids, name, startCodons };
}
function createCodonTable(aminoAcids: string): Readonly<Record<string, string>> {
if (aminoAcids.length !== 64) throw new Error("A genetic-code definition must contain exactly 64 residues.");
const table: Record<string, string> = {};
let index = 0;
for (const first of CODON_ORDER) for (const second of CODON_ORDER) for (const third of CODON_ORDER) {
table[`${first}${second}${third}`] = aminoAcids[index] ?? "X";
index += 1;
}
return Object.freeze(table);
}
function expandCodon(codon: string): Array<string> {
if (codon.length !== 3) return [];
let candidates = [""];
for (const symbol of codon) {
const expansion = [...expandNucleotideSymbol(symbol)];
if (expansion.length === 0) return [];
candidates = candidates.flatMap((prefix) => expansion.map((base) => `${prefix}${base}`));
}
return candidates;
}
SHA-256: 51514497d8b0188bdaa9c56044e2257defd99ea3dc3f6dcfb63c48fea5fabe55