123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335 |
- var Nt = function() {
-
- 'use strict';
-
- function makeArray(length, val) {
- if (val === undefined) { val = 0|0; }
- if (val < 0) { val = 0; }
- length |= 0;
- var max = 0;
- for (var i = length; i !== 0; i >>>= 1) { max++; }
- var n = Array(max);
- n[0] = [val];
- for (i = 1; i < max; i++) {
- n[i] = n[i-1].concat(n[i-1]);
- }
- var a = [];
- for (var i = 0, l = length; l !== 0; l >>>= 1, i++) {
- if (l&1) {
- a = a.concat(n[i]);
- }
- }
- return a;
- };
-
- var __bitCount = (function() {
- var a = new Uint8Array(256);
- var bin;
- for (var i = 0; i < 256; i++) {
- bin = i;
- bin = bin - ((bin >> 1) & 0x55555555);
- bin = (bin & 0x33333333) + ((bin >> 2) & 0x33333333);
- a[i] = (((bin + (bin >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
- }
- return a;
- })();
-
- var __nucleotideTo4Bit = Object.create(null);
- __nucleotideTo4Bit['A'] = 8; // 0b1000
- __nucleotideTo4Bit['T'] = 4; // 0b0100
- __nucleotideTo4Bit['G'] = 2; // 0b0010
- __nucleotideTo4Bit['C'] = 1; // 0b0001
-
- function setNucleotide() {
- var n = arguments[0];
- __nucleotideTo4Bit[n] = 0;
- for (var i = 1; i < arguments.length; i++) {
- __nucleotideTo4Bit[n] |= __nucleotideTo4Bit[arguments[i]];
- }
- };
-
- setNucleotide('-');
- setNucleotide('W', 'A', 'T');
- setNucleotide('S', 'G', 'C');
- setNucleotide('M', 'A', 'C');
- setNucleotide('K', 'G', 'T');
- setNucleotide('R', 'A', 'G');
- setNucleotide('Y', 'C', 'T');
- setNucleotide('B', 'C', 'G', 'T');
- setNucleotide('D', 'A', 'G', 'T');
- setNucleotide('H', 'A', 'C', 'T');
- setNucleotide('V', 'A', 'C', 'G');
- setNucleotide('N', 'A', 'T', 'G', 'C');
-
- var __4BitToNucleotide = (
- function() {
- var a = makeArray(16);
- var keys = Object.keys(__nucleotideTo4Bit);
- for (var i = 0, len = keys.length; i < len; i++) {
- a[__nucleotideTo4Bit[keys[i]]] = keys[i];
- }
- return a;
- }
- )();
-
- var __nucleotideList = Object.keys(__nucleotideTo4Bit);
-
- var __complementNucleotide = (
- function() {
- var a = Object.create(null);
- a['A'] = 'T';
- a['G'] = 'C';
- a['B'] = 'V';
- a['H'] = 'D';
- a['M'] = 'K';
- a['R'] = 'Y';
- // S, W, N, - not included
- var keys = Object.keys(a);
- for (var i = 0, len = keys.length; i < len; i++) {
- a[a[keys[i]]] = keys[i];
- }
- a['S'] = 'S';
- a['W'] = 'W';
- a['N'] = 'N';
- a['-'] = '-';
- return a;
- }
- )();
-
- var __complement4Bit = (
- function() {
- var a = new Uint8Array(16);
- for (var i = 0, len = a.length; i < len; i++) {
- a[i] = __nucleotideTo4Bit[__complementNucleotide[__4BitToNucleotide[i]]];
- }
- return a;
- }
- )();
-
- function nucleotideToBin(s) {
- return __nucleotideTo4Bit[s] | 0;
- }
-
- function binToNucleotide(b) {
- return __4BitToNucleotide[b] || '-';
- }
-
- function complementNucleotide(s) {
- return __complementNucleotide[s] || '-';
- }
-
- function complementBin(b) {
- return __complement4Bit[b] | 0;
- }
-
- /* Double up to form bytes */
- var __byteComplement;
- var __nucleotidesToByte;
- var __byteToNucleotides;
- var __byteNucleotideContent;
-
- void function() {
-
- var a = Object.create(null);
- var b = new Uint8Array(256);
- var c = new makeArray(256);
- var d = new makeArray(256);
-
- var keys = Object.keys(__nucleotideTo4Bit);
- var len = keys.length;
- var ki;
- var kj;
- var byte;
-
- for (var i = 0; i < len; i++) {
- ki = keys[i];
- for (var j = 0; j < len; j++) {
- kj = keys[j];
- byte = __nucleotideTo4Bit[ki] | (__nucleotideTo4Bit[kj] << 4);
- a[ki + kj] = byte;
- b[byte] = __nucleotideTo4Bit[complementNucleotide(kj)] | (__nucleotideTo4Bit[complementNucleotide(ki)] << 4);
- c[byte] = ki + kj;
- d[byte] = [ki, kj];
- }
- }
-
- __nucleotidesToByte = a;
- __byteComplement = b;
- __byteToNucleotides = c;
- __byteNucleotideContent = d;
-
- }();
-
- function nucleotidesToByte(ss) {
- return __nucleotidesToByte[ss] | 0;
- }
-
- /* amino acids */
-
- var __codonToAminoAcid = Object.create(null);
- __codonToAminoAcid['AAA'] = 'K';
- __codonToAminoAcid['AAT'] = 'N';
- __codonToAminoAcid['AAG'] = 'K';
- __codonToAminoAcid['AAC'] = 'N';
- __codonToAminoAcid['ATA'] = 'I';
- __codonToAminoAcid['ATT'] = 'I';
- __codonToAminoAcid['ATG'] = 'M';
- __codonToAminoAcid['ATC'] = 'I';
- __codonToAminoAcid['AGA'] = 'R';
- __codonToAminoAcid['AGT'] = 'S';
- __codonToAminoAcid['AGG'] = 'R';
- __codonToAminoAcid['AGC'] = 'S';
- __codonToAminoAcid['ACA'] = 'T';
- __codonToAminoAcid['ACT'] = 'T';
- __codonToAminoAcid['ACG'] = 'T';
- __codonToAminoAcid['ACC'] = 'T';
- __codonToAminoAcid['TAA'] = '*';
- __codonToAminoAcid['TAT'] = 'Y';
- __codonToAminoAcid['TAG'] = '&';
- __codonToAminoAcid['TAC'] = 'Y';
- __codonToAminoAcid['TTA'] = 'L';
- __codonToAminoAcid['TTT'] = 'F';
- __codonToAminoAcid['TTG'] = 'L';
- __codonToAminoAcid['TTC'] = 'F';
- __codonToAminoAcid['TGA'] = '$';
- __codonToAminoAcid['TGT'] = 'C';
- __codonToAminoAcid['TGG'] = 'W';
- __codonToAminoAcid['TGC'] = 'C';
- __codonToAminoAcid['TCA'] = 'S';
- __codonToAminoAcid['TCT'] = 'S';
- __codonToAminoAcid['TCG'] = 'S';
- __codonToAminoAcid['TCC'] = 'S';
- __codonToAminoAcid['GAA'] = 'E';
- __codonToAminoAcid['GAT'] = 'D';
- __codonToAminoAcid['GAG'] = 'E';
- __codonToAminoAcid['GAC'] = 'D';
- __codonToAminoAcid['GTA'] = 'V';
- __codonToAminoAcid['GTT'] = 'V';
- __codonToAminoAcid['GTG'] = 'V';
- __codonToAminoAcid['GTC'] = 'V';
- __codonToAminoAcid['GGA'] = 'G';
- __codonToAminoAcid['GGT'] = 'G';
- __codonToAminoAcid['GGG'] = 'G';
- __codonToAminoAcid['GGC'] = 'G';
- __codonToAminoAcid['GCA'] = 'A';
- __codonToAminoAcid['GCT'] = 'A';
- __codonToAminoAcid['GCG'] = 'A';
- __codonToAminoAcid['GCC'] = 'A';
- __codonToAminoAcid['CAA'] = 'Q';
- __codonToAminoAcid['CAT'] = 'H';
- __codonToAminoAcid['CAG'] = 'Q';
- __codonToAminoAcid['CAC'] = 'H';
- __codonToAminoAcid['CTA'] = 'L';
- __codonToAminoAcid['CTT'] = 'L';
- __codonToAminoAcid['CTG'] = 'L';
- __codonToAminoAcid['CTC'] = 'L';
- __codonToAminoAcid['CGA'] = 'R';
- __codonToAminoAcid['CGT'] = 'R';
- __codonToAminoAcid['CGG'] = 'R';
- __codonToAminoAcid['CGC'] = 'R';
- __codonToAminoAcid['CCA'] = 'P';
- __codonToAminoAcid['CCT'] = 'P';
- __codonToAminoAcid['CCG'] = 'P';
- __codonToAminoAcid['CCC'] = 'P';
-
- var __12BitToAminoAcid = (function() {
-
- var a = makeArray(4096, '?');
- var codons = Object.keys(__codonToAminoAcid);
- var codon;
- for (var i = 0, len = codons.length; i < len; i++) {
- codon = codons[i];
- a[
- (nucleotideToBin(codon[2]) << 8) |
- (nucleotideToBin(codon[1]) << 4) |
- nucleotideToBin(codon[0])
- ] = __codonToAminoAcid[codon];
- }
-
- return a;
-
- })();
-
- function Seq(type) {
-
- if (type === undefined) {
- type = 'DNA';
- }
-
- if (!{'RNA': true, 'DNA': true}[type]) {
- throw new Error('Sequence type ' + type + ' not supported');
- }
-
- this.__type = type;
- this.__isRNA = (type === 'RNA');
-
- this.__endPadding = 0;
-
- this.__buffer = new ArrayBuffer(4);
-
- this.__complement = null;
-
- this.__content = null;
- this.__fractionalContent = null;
- this.__contentATGC = null;
- this.__fractionalContent = null;
-
- };
-
- Seq.prototype.read = function(strData) {
-
- var ntToByte = nucleotidesToByte;
-
- var nucleotideString = strData.toUpperCase()
- .replace(/\s/g, '')
- .replace('U', 'T')
- .replace(/[^ATGCBVHDMKRYSWN\-]/g, '-');
-
- var length = nucleotideString.length | 0;
- var max = length >>> 1;
- var odd = length & 1;
-
- var endPadding = (4 - (max + odd) % 4) % 4;
- this.__endPadding = endPadding;
-
- var buffer = new ArrayBuffer(max + odd + endPadding + 4);
- var dataArray = new Int8Array(buffer, 4);
-
- var n;
- var byte;
- var content;
-
- for (var i = 0; i < max; i++) {
-
- n = i << 1;
- dataArray[i] = ntToByte(nucleotideString[n] + nucleotideString[++n]);
-
- }
-
- if (odd) {
-
- dataArray[i] = __nucleotideTo4Bit[nucleotideString[i << 1]];
-
- }
-
- this.__buffer = buffer;
- this.__length = length;
- (new Uint32Array(buffer, 0, 1))[0] = length;
-
- this.__complement = null;
-
- this.__content = null;
- this.__fractionalContent = null;
- this.__contentATGC = null;
- this.__fractionalContent = null;
-
- return this;
-
- };
-
- Seq.prototype.readFASTA = function(strFASTA) {
-
- var data = strFASTA.split(/\n\r?/gi);
-
- while (data.length && data[0][0] === '>') {
- data.shift();
- }
-
- return this.read(data.join(''));
-
- };
-
- Seq.prototype.readBuffer = function(buffer) {
-
- this.__buffer = buffer;
-
- var length = (new Uint32Array(buffer, 0, 1))[0];
-
- var max = length >>> 1;
- var odd = length & 1;
-
- var endPadding = (4 - (max + odd) % 4) % 4;
- this.__endPadding = endPadding;
-
- this.__length = length;
-
- this.__complement = null;
-
- this.__content = null;
- this.__fractionalContent = null;
- this.__contentATGC = null;
- this.__fractionalContent = null;
-
- return this;
-
- };
-
- Seq.prototype.__byteComplement = function() {
-
- var bComp = __byteComplement;
-
- var fwdBuffer = this.__buffer;
- var len = fwdBuffer.byteLength;
-
- var n, i;
-
- var copyBuffer, fromArray, copyArray;
-
- var isOdd = this.__length & 1;
-
- if (isOdd) {
-
- copyBuffer = new ArrayBuffer(len);
- copyArray = new Uint32Array(copyBuffer, 4);
- fromArray = new Uint32Array(fwdBuffer, 4);
-
- n = (len - 4) >>> 2;
- while(n--) {
- copyArray[n] = (fromArray[n] << 4) | ((fromArray[n - 1]) >>> 28);
- }
-
- } else {
-
- copyBuffer = fwdBuffer;
-
- }
-
- var fwdArray = new Uint8Array(copyBuffer, 4);
-
- var buffer = new ArrayBuffer(len);
- var dataArray = new Uint8Array(buffer, 4);
-
- n = (len - 4) - this.__endPadding;
- i = 0;
- while(n--) {
- dataArray[i++] = bComp[fwdArray[n]];
- }
-
- (new Uint32Array(buffer, 0, 1))[0] = this.__length;
-
- return buffer;
-
- };
-
- Seq.prototype.size = function() {
- return this.__length;
- };
-
- Seq.prototype.sequence = function() {
-
- var byteToNt = __byteToNucleotides;
- var buffer = this.__buffer;
-
- if (buffer.byteLength < 4) {
- return '';
- }
-
- var dataArray = new Uint8Array(buffer, 4);
- var len = (buffer.byteLength - 4) - this.__endPadding;
-
- var nts = makeArray(len);
-
- for (var i = 0; i < len; i++) {
- nts[i] = byteToNt[dataArray[i]];
- }
-
- var returnString;
-
- i = nts.length - 1;
- if (this.__length & 1) {
- nts[i] = nts[i][0];
- }
-
- returnString = nts.join('');
-
- if (this.__isRNA) {
- returnString = returnString.replace(/T/gi, 'U');
- }
-
- return returnString;
-
- };
-
- Seq.prototype.complement = function() {
-
- if (!this.__complement) {
- this.__complement = this.__byteComplement();
- }
-
- var complement = new Seq(this.__type).readBuffer(this.__complement.slice(0));
-
- complement.__complement = this.__buffer.slice(0);
-
- return complement;
-
- };
-
- Seq.prototype.equivalent = function(seq) {
-
- if (!(seq instanceof Seq)) {
- throw new Error('Can only check for equivalence between sequences');
- }
-
- if (this.__type !== seq.__type) {
- return false;
- }
-
- var checkInts = new Uint32Array(this.__buffer);
- var compareInts = new Uint32Array(seq.__buffer);
-
- for (var i = 0, len = checkInts.length; i < len; i++) {
- if (checkInts[i] !== compareInts[i]) {
- return false;
- }
- }
-
- return true;
-
- };
-
- Seq.prototype.replicate = function(start, length) {
-
- start |= 0;
-
- if (start < 0) {
- start = this.__length + start;
- }
-
- if (length === undefined) {
-
- if (start === 0) {
-
- return this.__clone();
-
- }
-
- length = this.__length - start;
-
- } else {
-
- length |= 0;
- length = Math.min(length, this.__length - start);
-
- }
-
- length = Math.min(length, this.__length - start);
-
- if (length <= 0) {
-
- return this.__nullSeq();
-
- }
-
- return this.__slice(start, length);
-
- };
-
- Seq.prototype.polymerize = function(seq) {
-
- var seqLen = seq.__length;
-
- if (!(seq instanceof Seq)) {
- throw new Error('.polymerize requires valid sequence');
- }
-
- if (!this.__length) {
- return seq.__clone();
- }
-
- var offset = this.__length;
- var length = this.__length + seqLen;
-
- var max = length >>> 1;
- var odd = length & 1;
-
- var endPadding = (4 - (max + odd) % 4) % 4;
- var newBuffer = new ArrayBuffer(max + odd + endPadding + 4);
- var newArray = new Uint32Array(newBuffer, 4);
-
- var copyBuffer = this.__buffer;
- var copyArray = new Uint32Array(copyBuffer, 4);
-
- var seqBuffer = seq.__buffer;
- var seqArray = new Uint32Array(seqBuffer, 4);
-
- var copyPos = 0;
- var shift = (this.__length % 8) * 4;
- var shiftSeq = 32 - shift;
-
- for (var len = copyArray.length; copyPos < len; copyPos++) {
- newArray[copyPos] = copyArray[copyPos];
- }
-
- if (shift) {
-
- newArray[--copyPos] |= seqArray[0] << shift;
-
- for (var i = 0, len = seqArray.length; i < len; i++) {
- newArray[++copyPos] = (seqArray[i] >>> shiftSeq) | (seqArray[i + 1] << shift);
- }
-
- } else {
-
- for (var i = 0, len = seqArray.length; i < len; i++) {
- newArray[copyPos++] = seqArray[i];
- }
-
- }
-
- (new Uint32Array(newBuffer, 0, 1))[0] = length;
-
- return new Seq(this.__type).readBuffer(newBuffer);
-
- };
-
- Seq.prototype.insertion = function(seq, offset) {
-
- if (!(seq instanceof Seq)) {
- throw new Error('Insertion requires valid sequence');
- }
-
- offset |= 0;
-
- if (offset < 0) {
- offset = this.__length + offset;
- }
-
- offset = Math.min(offset, this.__length);
-
- return this.replicate(0, offset).polymerize(seq).polymerize(this.replicate(offset));
-
- };
-
- Seq.prototype.deletion = function(offset, count) {
-
- if (offset === undefined || count === undefined) {
- throw new Error('Must give valid offset and count for deletion');
- }
-
- offset |= 0;
- count |= 0;
-
- if (count === 0) {
- return this.__clone();
- }
-
- if (count < 0) {
- throw new Error('Invalid count for deletion');
- }
-
- if (offset < 0) {
- offset = this.__length + offset;
- }
-
- offset = Math.min(offset, this.__length);
-
- return this.replicate(0, offset).polymerize(this.replicate(offset + count));
-
- };
-
- Seq.prototype.repeat = function(count) {
-
- count |= 0;
-
- var copy = this.replicate();
- var base = new Seq(this.__type);
-
- if (count <= 0) {
- return base;
- }
-
- while(true) {
- if (count & 1) {
- base = base.polymerize(copy);
- }
- count >>>= 1;
- if (!count) {
- break;
- }
- copy = copy.polymerize(copy);
- }
-
- return base;
-
- };
-
- Seq.prototype.mask = function(seq) {
-
- if (!(seq instanceof Seq)) {
- throw new Error('Can only mask with valid sequence');
- }
-
- var newBuffer = this.__buffer.slice(0);
- var newArray = new Uint32Array(newBuffer, 4);
- var compareArray = new Uint32Array(seq.__buffer, 4);
-
- for (var i = 0, len = newArray.length; i < len; i++) {
- newArray[i] &= compareArray[i];
- }
-
- return new Seq(this.__type).readBuffer(newBuffer);
-
- };
-
- Seq.prototype.cover = function(seq) {
-
- if (!(seq instanceof Seq)) {
- throw new Error('Can only cover with valid sequence');
- }
-
- var newBuffer = this.__buffer.slice(0);
- var newArray = new Uint32Array(newBuffer, 4);
- var compareArray = new Uint32Array(seq.__buffer, 4);
-
- for (var i = 0, len = newArray.length; i < len; i++) {
- newArray[i] |= compareArray[i];
- }
-
- return new Seq(this.__type).readBuffer(newBuffer);
-
- };
-
- Seq.prototype.__nullSeq = function() {
-
- return new Seq(this.__type).readBuffer(new ArrayBuffer(4));
-
- };
-
- Seq.prototype.__clone = function() {
-
- return new Seq(this.__type).readBuffer(this.__buffer.slice(0));
-
- };
-
- Seq.prototype.__slice = function(start, length) {
-
- var max = length >>> 1;
- var odd = length & 1;
-
- var endPadding = (4 - (max + odd) % 4) % 4;
- var newBuffer = new ArrayBuffer(max + odd + endPadding + 4);
- var newArray = new Uint32Array(newBuffer, 4);
-
- var subBuffer = this.__buffer.slice(4 + (start >>> 1), 4 + (start >>> 1) + newBuffer.byteLength);
- var subInt32Length = subBuffer.byteLength >>> 2;
- var subArray = new Uint32Array(subBuffer, 0, subInt32Length);
-
- if (start & 1) {
-
- for (var i = 0, len = subArray.length; i < len; i++) {
- newArray[i] = (subArray[i] >>> 4) | (subArray[i + 1] << 28);
- }
-
- var remainder = subBuffer.byteLength - subArray.byteLength;
- if (remainder) {
- var remainderArray = new Uint8Array(newBuffer, 4 + (i << 2));
- var subRemainderArray = new Uint8Array(subBuffer, i << 2);
- if (newArray.length > 0) {
- newArray[i - 1] |= subRemainderArray[0] << 28;
- }
- for (var i = 0, len = subRemainderArray.length; i < len; i++) {
- remainderArray[i] = (subRemainderArray[i] >>> 4) | (subRemainderArray[i + 1] << 4);
- }
- }
-
- } else {
-
- for (var i = 0, len = subArray.length; i < len; i++) {
- newArray[i] = subArray[i];
- }
-
- var remainder = subArray.byteLength - subBuffer.byteLength;
- if (remainder) {
- var remainderArray = new Uint8Array(newBuffer, 4 + (i << 2));
- var subRemainderArray = new Uint8Array(subBuffer, i << 2);
- for (var i = 0, len = subRemainderArray.length; i < len; i++) {
- remainderArray[i] = subRemainderArray[i];
- }
- }
-
- }
-
- var clearShift = ((endPadding * 2) + odd) * 4;
-
- var clearOut = new Uint32Array(newBuffer, newBuffer.byteLength - 4);
- clearOut[0] = (clearOut[0] << clearShift) >>> clearShift;
-
- (new Uint32Array(newBuffer, 0, 1))[0] = length;
-
- return new Seq(this.__type).readBuffer(newBuffer);
-
- };
-
- Seq.prototype.content = function() {
-
- if (!this.__content) {
-
- var ntContentByte = makeArray(256);
-
- var buffer = this.__buffer;
- var dataArray = new Uint8Array(buffer);
-
- for(var i = 4; i < buffer.byteLength - this.__endPadding; i++) {
- ntContentByte[dataArray[i]]++;
- }
-
- var binToNt = binToNucleotide;
- var ntList = __nucleotideList;
-
- var ntContent = Object.create(null);
- for (var i = 0, len = ntList.length; i < len; i++) {
- ntContent[ntList[i]] = 0;
- }
-
- for (var i = 0, len = ntContentByte.length; i < len; i++) {
- if (ntContentByte[i]) {
- ntContent[binToNt(i & 0xF)] += ntContentByte[i];
- ntContent[binToNt(i >>> 4)] += ntContentByte[i];
- }
- }
-
- if (this.__length & 1) {
- ntContent['-']--;
- }
-
- if (this.__isRNA) {
- ntContent['U'] = ntContent['T'];
- delete ntContent['T'];
- }
-
- this.__content = ntContent;
-
- }
-
- var returnContent = Object.create(null);
- var keys = Object.keys(this.__content);
- for (var i = 0, len = keys.length; i < len; i++) {
- returnContent[keys[i]] = this.__content[keys[i]];
- }
-
- return returnContent;
-
- };
-
- Seq.prototype.fractionalContent = function() {
-
- if (!this.__fractionalContent) {
-
- var content = this.content();
- var nts = Object.keys(content);
- for (var i = 0, len = nts.length; i < len; i++) {
- content[nts[i]] = content[nts[i]] / this.__length;
- }
-
- this.__fractionalContent = content;
-
- }
-
- var returnContent = Object.create(null);
- var keys = Object.keys(this.__fractionalContent);
- for (var i = 0, len = keys.length; i < len; i++) {
- returnContent[keys[i]] = this.__fractionalContent[keys[i]];
- }
-
- return returnContent;
-
- };
-
- Seq.prototype.contentATGC = function() {
-
- if (!this.__contentATGC) {
-
- var ntToBin = nucleotideToBin;
-
- var content = this.content();
- var nts = Object.keys(content);
- var contentATGC = Object.create(null);
- contentATGC['A'] = 0;
- contentATGC['T'] = 0;
- contentATGC['G'] = 0;
- contentATGC['C'] = 0;
-
- var bits = 0;
- var nt;
- var ntBin;
- var n;
- var curContent;
-
- for (var i = 0, len = nts.length; i < len; i++) {
- nt = nts[i];
- n = ntToBin(nt);
- for (bits = 0; n; bits++) { n &= n - 1; }
-
- ntBin = ntToBin(nt);
- curContent = content[nts[i]] * (1 / bits);
-
- contentATGC['A'] += (((ntToBin('A') & ntBin) | 0) && curContent);
- contentATGC['T'] += (((ntToBin('T') & ntBin) | 0) && curContent);
- contentATGC['G'] += (((ntToBin('G') & ntBin) | 0) && curContent);
- contentATGC['C'] += (((ntToBin('C') & ntBin) | 0) && curContent);
-
- }
-
- if (this.__isRNA) {
- contentATGC['U'] = contentATGC['T'];
- delete contentATGC['T'];
- }
-
- this.__contentATGC = contentATGC;
-
- }
-
- var returnContent = Object.create(null);
- var keys = Object.keys(this.__contentATGC);
- for (var i = 0, len = keys.length; i < len; i++) {
- returnContent[keys[i]] = this.__contentATGC[keys[i]];
- }
-
- return returnContent;
-
- };
-
- Seq.prototype.fractionalContentATGC = function() {
-
- if (!this.__fractionalContentATGC) {
-
- var content = this.contentATGC();
- var nts = Object.keys(content);
- for (var i = 0, len = nts.length; i < len; i++) {
- content[nts[i]] = content[nts[i]] / this.__length;
- }
-
- this.__fractionalContentATGC = content;
-
- }
-
- var returnContent = Object.create(null);
- var keys = Object.keys(this.__fractionalContentATGC);
- for (var i = 0, len = keys.length; i < len; i++) {
- returnContent[keys[i]] = this.__fractionalContentATGC[keys[i]];
- }
-
- return returnContent;
-
- };
-
- Seq.prototype.translate = function(ntOffset, ntCount) {
-
- var binToAA = __12BitToAminoAcid;
-
- ntOffset |= 0;
-
- if (ntCount === undefined) {
- ntCount = this.__length - ntOffset;
- }
-
- ntCount |= 0;
- ntCount -= (ntCount % 3);
-
- var offset = (ntOffset >>> 1) + 4;
- var max = offset + (ntCount >>> 1) + (ntCount & 1);
-
- var dataArray = new Uint8Array(this.__buffer);
-
- var aminoAcids = makeArray(ntCount / 3);
- /**/
- var aa = 0;
- var lastByte, byte1, byte2, byte3;
-
- if ((ntOffset & 1) === 0) {
-
- for (var i = offset; i < max; i += 3) {
-
- var byte1 = dataArray[i];
- var byte2 = dataArray[i+1];
- var byte3 = dataArray[i+2];
-
- aminoAcids[aa++] = binToAA[byte1 | ((byte2 & 0xF) << 8)];
- aminoAcids[aa++] = binToAA[(byte3 << 4) | (byte2 >>> 4)];
-
- }
-
- } else {
-
- lastByte = dataArray[offset];
-
- for (var i = offset + 1; i < max; i += 3) {
-
- byte1 = dataArray[i];
- byte2 = dataArray[i+1];
- byte3 = dataArray[i+2];
-
- aminoAcids[aa++] = binToAA[(lastByte >> 4) | (byte1 << 4)];
- aminoAcids[aa++] = binToAA[byte2 | ((byte3 & 0xF) << 8)];
-
- lastByte = byte3;
-
- }
-
- }
-
- if (ntCount & 1) { aminoAcids.pop(); }
-
- return aminoAcids.join('');
-
- };
-
- Seq.prototype.translateFrame = function(frame, AAoffset, AAcount) {
-
- if (frame === undefined) {
- frame = 0;
- }
-
- if (frame !== 0 && frame !== 1 && frame !== 2) {
- throw new Error('Invalid translation frame, must be 0, 1 or 2.');
- }
-
- if (AAoffset === undefined) {
- return this.translate(frame);
- }
-
- if (AAcount === undefined) {
- return this.translate(frame + ((AAoffset | 0) * 3));
- }
-
- return this.translate(frame + ((AAoffset | 0) * 3), (AAcount * 3) | 0);
-
- };
-
- Seq.prototype.mapSequence = function(seq, offset) {
-
- if (!(seq instanceof Seq)) {
- throw new Error('.mapSequence requires valid Seq');
- }
-
- return new MatchMap(seq, this, offset);
-
- };
-
- /* MatchResult */
-
- function MatchResult(matchMap, pos, score) {
-
- Object.defineProperty(this, '__matchMap', {value: matchMap});
-
- this.position = pos;
- this.score = score;
- this.__align = null;
-
- };
-
- MatchResult.prototype.alignment = function() {
-
- if (!this.__align) {
- var map = this.__matchMap;
- if (this.position < 0) {
- this.__align = (new Nt.Seq())
- .read('-')
- .repeat(-this.position)
- .polymerize(map.__searchSpace.replicate(0, map.__query.__length + this.position));
- } else if (this.position + map.__query.__length > map.__searchSpace.__length) {
- this.__align = map.__searchSpace
- .replicate(this.position)
- .polymerize((new Nt.Seq()).read('-').repeat(map.__searchSpace.__length - this.position));
- } else {
- this.__align = map.__searchSpace.replicate(this.position, map.__query.__length);
- }
- }
- return this.__align;
-
- };
-
- MatchResult.prototype.alignmentMask = function() {
-
- return this.__matchMap.__query.mask(this.alignment());
-
- };
-
- MatchResult.prototype.alignmentCover = function() {
-
- return this.__matchMap.__query.cover(this.alignment());
-
- };
-
- /* MatchMap */
-
- function MatchMap(query, searchSpace, offset) {
-
- if (!(query instanceof Seq) || !(searchSpace instanceof Seq)) {
- throw new Error('MatchMap requires valid Seq');
- }
-
- this.__query = query.replicate();
- this.__searchSpace = searchSpace.replicate();
- this.__results = [];
- this.__orderedResults = [];
- this.__matchFrequencyData = null;
- this.__initialized = false;
-
- this.__offset = Math.max(0, offset | 0);
- this.__positionAdjustment = this.__offset - (this.__query.size() - 1);
-
- this.__debug = {
- searchTime: null,
- prepareTime: null,
- sortTime: null
- };
-
- };
-
- MatchMap.prototype.initialize = function(results) {
-
- this.__orderedResults = [];
- this.__matchFrequencyData = null;
-
- this.__initialized = true;
-
- var t = (new Date).valueOf();
-
- if (!results) {
-
- var dataArray = new Uint32Array(this.__execute(this.__query.__buffer, this.__searchSpace.__buffer));
-
- this.__debug.searchTime = (-t) + (t = (new Date).valueOf());
-
- var queryLen = this.__query.size();
- var searchLen = this.__searchSpace.size();
- var resultsLen = ((8 - (queryLen % 8)) % 8) + 1;
- var totalLen = searchLen + queryLen - 1;
- results = [].slice.call(dataArray, resultsLen, resultsLen + totalLen);
-
- }
-
- this.__results = results;
- this.__debug.prepareTime = (-t) + (t = (new Date).valueOf());
-
- return this;
-
- };
-
- MatchMap.prototype.sort = function() {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- var t = new Date().valueOf();
-
- if (this.__debug.sortTime !== null) {
- return this;
- }
-
- var adjust = this.__positionAdjustment;
- this.__orderedResults = this.__results
- .map(function(v, i) { return {n: i + adjust, s: v}; })
- .sort(function(a, b) { return b.s - a.s; });
- this.__debug.sortTime = new Date().valueOf() - t;
- return this;
-
- };
-
- MatchMap.prototype.__calculate_p_match = function(query, searchSpace) {
-
- /*
- The approximate probability that two randomly chosen nucleotides
- from QUERY and SEARCH match each other
- */
-
- var queryContent = query.fractionalContentATGC();
- var searchSpaceContent = searchSpace.fractionalContentATGC();
-
- return (queryContent['A'] * searchSpaceContent['A']) +
- (queryContent['T'] * searchSpaceContent['T']) +
- (queryContent['G'] * searchSpaceContent['G']) +
- (queryContent['C'] * searchSpaceContent['C']);
-
- };
-
- MatchMap.prototype.results = function(offset, count) {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- if (offset === undefined) {
- return this.__results.slice();
- }
-
- if (count === undefined) {
- return this.__results.slice(offset | 0);
- }
-
- return this.__results.slice(offset | 0, count | 0);
-
- };
-
- MatchMap.prototype.best = function() {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- if (!this.__orderedResults.length) {
- throw new Error('MatchMap must be sorted first.');
- }
-
- var result = this.__orderedResults[0];
- return new MatchResult(this, result.n, result.s);
-
- };
-
- MatchMap.prototype.top = function(n) {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- if (!this.__orderedResults.length) {
- throw new Error('MatchMap must be sorted first.');
- }
-
- var self = this;
-
- return this.__orderedResults.slice(0, n).map(function(result) {
- return new MatchResult(self, result.n, result.s);
- });
-
- };
-
- MatchMap.prototype.bottom = function(n) {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- if (!this.__orderedResults.length) {
- throw new Error('MatchMap must be sorted first.');
- }
-
- var self = this;
-
- var adjust = this.__positionAdjustment;
- var len = this.__orderedResults.length;
- return this.__orderedResults.slice(this.__orderedResults.length - n, n).map(function(result) {
- return new MatchResult(self, result.n, result.s);
- });
-
- };
-
- /* Can be optimized with binary splitting */
-
- MatchMap.prototype.matchFrequencyData = function() {
-
- if (!this.__initialized) {
- throw new Error('MatchMap must be initialized first.');
- }
-
- if (!this.__orderedResults.length) {
- throw new Error('MatchMap must be sorted first.');
- }
-
- if (this.__matchFrequencyData) {
- return this.__matchFrequencyData;
- }
-
- var ordered = this.__orderedResults;
- var matchFrequencyData = makeArray(this.__query.size() + 1);
-
- var maxMatch = this.__query.size();
- var lastIndex = 0;
- var num;
-
- for (var i = 0, len = ordered.length; i < len; i++) {
- num = ordered[i].s;
- if (num < maxMatch) {
- matchFrequencyData[maxMatch] = i - lastIndex;
- lastIndex = i;
- maxMatch = num;
- }
- if (num === 0) {
- matchFrequencyData[0] = len - i;
- break;
- }
- }
-
- return (this.__matchFrequencyData = matchFrequencyData);
-
- };
-
- MatchMap.prototype.__countMatches = function(int, bitCount) {
-
- int |= int >>> 1;
- int |= int >>> 2;
- int &= 0x11111111;
- int |= int >>> 3;
- int |= int >>> 6;
- return bitCount[((int >>> 12) & 0xF0) | (int & 0xF)];
-
- };
-
- MatchMap.prototype.__execute = function(queryBuffer, searchSpaceBuffer) {
-
- var queryInts, spaceInts, queryIntsLength, spaceIntsLength,
- arrLen, mapBuffer, mapArray,
- A, B, A1, A2, T, cur, pos, move, i, k,
- adjustNeg, adjustPos,
- fnCountMatches, bitCount;
-
- queryInts = new Uint32Array(queryBuffer, 4);
- spaceInts = new Uint32Array(searchSpaceBuffer, 4);
-
- fnCountMatches = this.__countMatches;
- bitCount = __bitCount;
-
- queryIntsLength = queryInts.length|0;
- spaceIntsLength = spaceInts.length|0;
-
- arrLen = (queryIntsLength + spaceIntsLength) << 3;
- mapBuffer = new ArrayBuffer(4 * arrLen);
- mapArray = new Uint32Array(mapBuffer);
-
- for (k = 0|0; k < queryIntsLength; k++) {
-
- A = queryInts[k];
- cur = (queryIntsLength - k) << 3;
-
- for (i = 0|0; i < spaceIntsLength; i++) {
- (T = A & spaceInts[i]) && (mapArray[(i << 3) + cur] += fnCountMatches(T, bitCount));
- }
-
- A1 = A >>> 4;
- A2 = A << 4;
-
- adjustNeg = cur - 1;
- adjustPos = cur + 1;
-
- while(A1 || A2) {
-
- for (i = 0|0; i < spaceIntsLength; i++) {
- B = spaceInts[i];
- pos = (i << 3);
-
- (T = A1 & B) && (mapArray[pos + adjustNeg] += fnCountMatches(T, bitCount));
- (T = A2 & B) && (mapArray[pos + adjustPos] += fnCountMatches(T, bitCount));
- }
-
- A1 >>>= 4;
- A2 <<= 4;
-
- --adjustNeg;
- ++adjustPos;
-
- }
-
- }
-
- return mapBuffer;
-
- };
-
- return {
- Seq: Seq,
- MatchMap: MatchMap
- };
-
- }();
|