|
| 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