Skip to content

Commit b28b9c8

Browse files
committed
JavaScript code to demonstrate an object-oriented approach. The code translates DNA sequence into amino acids and deals with IUPAC-specified base ambiguities.
1 parent 6649263 commit b28b9c8

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

TranslateDna.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
JavaScript object that translates a DNA input sequence into a protein sequence.
3+
It uses the "Combination Constructor/Prototype Pattern" as described in the book "Professional JavaScript For Web Developers"
4+
by Nicholas Zakas.
5+
The code is described in link "http://www.javascript-spreadsheet-programming.com/2012/12/object-oriented-javascript-example.html".
6+
The scientific background is given in "http://www.javascript-spreadsheet-programming.com/2012/11/using-github-for-javascript-and-vba.html"
7+
USE:
8+
Useful if you wish to translate a DNA sequence that contains IUPAC ambiguity codes.
9+
To use (Executed by Node.js): Append the three code lines below to the code file and execute from the command line with:
10+
node TranslateDna.js
11+
12+
var seq = 'CCTKAGATCACTCTTTGGCAACGACCCCTCGTCACAATAAAGATAGGGGGGCAACTAAAGGAAGCTCTATTAGATACAGGAGCAGATGATACAGTATTAGAAGAAATGAATTTGCCAGGAAGATGGAAACCAAAAATGATAGGGGGAATTGGAGGTTTTATCAAAGTAAGACAGTATGATCAGATACTCATAGAAATCTGTGGACATAAAGCTATAGGTACAGTATTAATAGGACCTACACCTGTCAACATAATTGGAAGAAATCTGTTGACTCAGCTTGGTTGCACTTTAAATTTT';
13+
var trans = new TranslateDna(seq);
14+
console.log(trans.getAminoAcids());
15+
16+
Passes JSLint without error when using the default settings.
17+
*/
18+
19+
// Constructor function sets instance variables.
20+
function TranslateDna(dnaSeq) {
21+
'use strict';
22+
this.dnaSeq = dnaSeq.toUpperCase();
23+
this.UNKNOWN = 'X';
24+
this.translateTable = {'GCT': 'A', 'GCC': 'A', 'GCA': 'A', 'GCG': 'A', 'CGT': 'R', 'CGC': 'R', 'CGA': 'R', 'CGG': 'R', 'AGA': 'R', 'AGG': 'R', 'AAT': 'N', 'AAC': 'N', 'GAT': 'D', 'GAC': 'D', 'TGT': 'C', 'TGC': 'C', 'CAA': 'Q', 'CAG': 'Q', 'GAA': 'E', 'GAG': 'E', 'GGT': 'G', 'GGC': 'G', 'GGA': 'G', 'GGG': 'G', 'CAT': 'H', 'CAC': 'H', 'ATT': 'I', 'ATC': 'I', 'ATA': 'I', 'TTA': 'L', 'TTG': 'L', 'CTT': 'L', 'CTC': 'L', 'CTA': 'L', 'CTG': 'L', 'AAA': 'K', 'AAG': 'K', 'ATG': 'M', 'TTT': 'F', 'TTC': 'F', 'CCT': 'P', 'CCC': 'P', 'CCA': 'P', 'CCG': 'P', 'TCT': 'S', 'TCC': 'S', 'TCA': 'S', 'TCG': 'S', 'AGT': 'S', 'AGC': 'S', 'ACT': 'T', 'ACC': 'T', 'ACA': 'T', 'ACG': 'T', 'TGG': 'W', 'TAT': 'Y', 'TAC': 'Y', 'GTT': 'V', 'GTC': 'V', 'GTA': 'V', 'GTG': 'V', 'TAG': '*', 'TGA': '*', 'TAA': '*'};
25+
this.iupacAmbiCodes = {'A': ['A'], 'C': ['C'], 'G': ['G'], 'T': ['T'], 'U': ['U'], 'M': ['A', 'C'], 'R': ['A', 'G'], 'W': ['A', 'T'], 'S': ['C', 'G'], 'Y': ['C', 'T'], 'K': ['G', 'T'], 'V': ['A', 'C', 'G'], 'H': ['A', 'C', 'T'], 'D': ['A', 'G', 'T'], 'B': ['C', 'G', 'T'], 'X': ['G', 'A', 'T', 'C'], 'N': ['G', 'A', 'T', 'C']};
26+
}
27+
28+
TranslateDna.prototype = {
29+
constructor: TranslateDna,
30+
// Perform lookup to return an amino acid for a given nucleotide triplet.
31+
getAminoAcid: function (codon) {
32+
'use strict';
33+
return this.translateTable[codon];
34+
},
35+
// Longest and most complex method. Used to disambiguate mixed triplets.
36+
getCodonsFromAmbiguous: function (ambiguousCodon) {
37+
'use strict';
38+
var codons = [],
39+
first = this.iupacAmbiCodes[ambiguousCodon.charAt(0)],
40+
lenFirst = first.length,
41+
second = this.iupacAmbiCodes[ambiguousCodon.charAt(1)],
42+
lenSecond = second.length,
43+
third = this.iupacAmbiCodes[ambiguousCodon.charAt(2)],
44+
lenThird = third.length,
45+
nuc1,
46+
nuc2,
47+
nuc3,
48+
codon,
49+
i,
50+
j,
51+
k;
52+
53+
for (i = 0; i < lenFirst; i += 1) {
54+
nuc1 = first[i];
55+
for (j = 0; j < lenSecond; j += 1) {
56+
nuc2 = second[j];
57+
for (k = 0; k < lenThird; k += 1) {
58+
nuc3 = third[k];
59+
codon = nuc1 + nuc2 + nuc3;
60+
codons.push(codon);
61+
}
62+
}
63+
}
64+
return codons;
65+
},
66+
// Break the instance DNA sequence string into triplets (codons). Assumes the DNA is in-frame.
67+
splitSequenceIntoTriplets: function () {
68+
'use strict';
69+
var i = 0,
70+
seqLen = this.dnaSeq.length,
71+
triplets = [],
72+
triplet;
73+
74+
for (i = 0; i < seqLen; i += 3) {
75+
triplet = this.dnaSeq.slice(i, 3 + i);
76+
triplets.push(triplet);
77+
}
78+
this.triplets = triplets;
79+
},
80+
//Return an array of triplets, if the instance is set, return it, else generate the triplets array and return it.
81+
getTriplets: function () {
82+
'use strict';
83+
if (!this.triplets) {
84+
this.splitSequenceIntoTriplets();
85+
}
86+
return this.triplets;
87+
},
88+
getAminoAcids: function () {
89+
'use strict';
90+
var triplets = this.getTriplets(),
91+
tripletCount = triplets.length,
92+
aminoAcids = [],
93+
aminoAcid,
94+
mixedTriplets = [],
95+
mixedAminoAcids = [],
96+
i,
97+
j;
98+
99+
for (i = 0; i < tripletCount; i += 1) {
100+
//Match only triplets composed of the four standard DNA nucleotide bases.
101+
if (triplets[i].match(/[ACGT]{3}/)) {
102+
aminoAcid = this.translateTable[triplets[i]];
103+
aminoAcids.push(aminoAcid);
104+
} else {
105+
//Allowable characters in input (four standard nucleotides A,C,G,T and all recognized IUPAC mixture codes).
106+
if (triplets[i].match(/[ACGTUMRWSYKVHDBXN]{3}/)) {
107+
mixedTriplets = this.getCodonsFromAmbiguous(triplets[i]);
108+
for (j = 0; j < mixedTriplets.length; j += 1) {
109+
aminoAcid = this.translateTable[mixedTriplets[j]];
110+
if (mixedAminoAcids.indexOf(aminoAcid) === -1) {
111+
mixedAminoAcids.push(aminoAcid);
112+
}
113+
}
114+
aminoAcids.push(mixedAminoAcids);
115+
} else {
116+
aminoAcids.push(this.UNKNOWN);
117+
}
118+
}
119+
}
120+
return aminoAcids;
121+
}
122+
};

0 commit comments

Comments
 (0)