UNPKG

htmol

Version:

NEXT-GENERATION MOLECULAR DYNAMICS WEB VISUALIZATION

565 lines (466 loc) 16.9 kB
class ReaderXTC{ constructor(client,st,e) { this.client=client; this.numframe = -1; this.trans=0; this.st = st; this.stop = 0; this.is_smaller; this.smallidx; this.flag; this.lsize; this.bitsize=0; this.natoms; this.e=e; this.sizeint = new Array(3); this.minint = new Array(3); this.maxint = new Array(3); this.sizesmall = new Array(3); this.part=new ArrayBuffer(); this.precision; this.inv_precision; this.smaller; this.small; this.tam; this.bnd=true; this.bndrev=false; this.iarr = 0; this.iarr1 = 0; this.iarr2 = 0; this.arreglo = new Float32Array(50000); this.arreglo1 = new Float32Array(50000); this.arreglo2 = new Float32Array(50000); this.FIRSTIDX = 9; this.ANGS_PER_NM = 10; this.xtc_magicints = [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216 ]; this.readstart = e.data.readstart; this.readend = e.data.readend; this.fpath = e.data.fpath; this.bsip = e.data.bsip; this.bslat = e.data.bslat; this.bslon = e.data.bslon; this.bsCont = e.data.bsCont; this.bsPais = e.data.bsPais; this.bsCd = e.data.bsCd; this.bsdatetime = e.data.bsdatetime; } validate() { this.client.send("fpath", { success: false, fpath: this.fpath, reqsize: false, verif: false, start: this.readstart, end: this.readend }); // the Binaryclient is ready to ask for the whole file console.log("HTMoL: is XTC"); } getFile(data,tam) { this.trans += data.byteLength; this.tam=tam; var tmp = new Uint8Array(this.part.byteLength + data.byteLength); tmp.set(new Uint8Array(this.part), 0); tmp.set(new Uint8Array(data), this.part.byteLength); this.part = tmp.buffer; if (trjFormat=='XTC') { if (this.st == 1) { if (this.bndrev == true) { for (var i = 0; i < 5; i++) { if (new DataView(this.part).getInt32(i) != 1995) { console.log("HTMoL3: ACA "); } else { this.part = this.part.slice(i); this.bndrev = false; console.log("HTMoL3: AQUI" + new DataView(this.part).getInt32(0)); break; } } } this.checkfile(this.part); this.st = 0; } if (this.stop == 0) { this.readhead(this.part); } } else { } } checkfile(buffer) { if (new DataView(buffer).getInt32(0) != 1995) { throw new Error("HTMoL3: Error. File is not an XTC-File! "); this.stop = 1; return -1; } this.natoms = new DataView(buffer).getInt32(4); if (this.natoms != this.e.data.natoms) { throw Error("HTMoL3: Bad format or number of atoms on file are not equal (TRJ:"+this.natoms+" PDB:"+this.e.data.natoms+")"); this.stop = 1; return -1; } } readhead(buffer) { //var x = new Array(3); //var y = new Array(3); //var z = new Array(3); var bitsizeint = new Array(3); var buf = new Array(4); var position = 0; //if(new DataView(buffer).getInt32(position)!=1995){ //return -1; //}else{ position += 4; //} //natoms = new DataView(buffer).getInt32(position); //if(natoms!=main.Obj3D.molecule.GetAtoms().length){ //alert("This file not is valid for this molecule"); //disconnect=true; //return; //} position += 4; //step = new DataView(buffer).getInt32(position); position += 4; //time = new DataView(buffer).getFloat32(position); position += 4; //for(i=0;i<3;i++){ //x[i] = new DataView(buffer).getFloat32(position); //y[i] = new DataView(buffer).getFloat32(position+4); //z[i] = new DataView(buffer).getFloat32(position+8); position += 36; //*36 without for cicle //} this.lsize = new DataView(buffer).getInt32(position); var size = this.lsize; position += 4; this.precision = new DataView(buffer).getFloat32(position); position += 4; for (var i = 0; i < 3; i++) { this.minint[i] = new DataView(buffer).getInt32(position); this.maxint[i] = new DataView(buffer).getInt32(position + 12); position += 4; } position += 12; this.sizeint[0] = this.maxint[0] - this.minint[0] + 1; this.sizeint[1] = this.maxint[1] - this.minint[1] + 1; this.sizeint[2] = this.maxint[2] - this.minint[2] + 1; if ((this.sizeint[0] | this.sizeint[1] | this.sizeint[2]) > 0xffffff) { bitsizeint[0] = this.xtc_sizeofint(this.sizeint[0]); bitsizeint[1] = this.xtc_sizeofint(this.sizeint[1]); bitsizeint[2] = this.xtc_sizeofint(this.sizeint[2]); this.bitsize = 0; // flag the use of large sizes } else { bitsizeint[0] = this.xtc_sizeofint(this.sizeint[0]); this.bitsize = this.xtc_sizeofints(3, this.sizeint); } this.smallidx = new DataView(buffer).getInt32(position); position += 4; this.smaller = (this.xtc_magicints[this.FIRSTIDX > this.smallidx - 1 ? this.FIRSTIDX : this.smallidx - 1] / 2) | 0; this.small = (this.xtc_magicints[this.smallidx] / 2) | 0; this.sizesmall[0] = this.sizesmall[1] = this.sizesmall[2] = (this.xtc_magicints[this.smallidx] >>> 0); buf[0] = new DataView(buffer).getInt32(position); position += 4; if (buf[0] < 0) return -1; if ((this.part.byteLength - 92) >= buf[0]) { this.part = buffer.slice(position); this.calculatecoords(this.part, buf); } } readFile(natoms) { if(!natoms){ var myfloat = this.arreglo.subarray(0, this.iarr); var myfloat1 = this.arreglo1.subarray(0, this.iarr1); var myfloat2 = this.arreglo2.subarray(0, this.iarr2); self.postMessage({ cmd: "enviar", dato: myfloat, dato1: myfloat1, dato2: myfloat2, bndarray: this.bnd }); this.trans = 0; this.st = 1; this.iarr = 0, this.iarr1 = 0, this.iarr2 = 0; self.postMessage({ cmd: "final", wast: this.part.byteLength - 1 }); this.bnd = !this.bnd; if (this.readend >= this.tam) { //console.log("HTMoL3: final"); this.bnd = true; this.readend = 0; this.readstart = 0; this.bndrev = false; self.postMessage({ cmd: "endfinal" }); this.client.send("fpath", { success: true, fpath: this.fpath, reqsize: false, verif: false, bsip: this.bsip, bslat: this.bslat, bslon: this.bslon, bsCont: this.bsCont, bsPais: this.bsPais, bsCd: this.bsCd, bsdatetime: this.bsdatetime }); // tell BinServer the Binaryclient has received the whole file } } } xtc_sizeofint(size) { var num = (1 >>> 0); var ssize = (size >>> 0); var nbits = 0; while (ssize >= num && nbits < 32) { nbits++; num <<= 1; } return nbits; } xtc_sizeofints(nints, sizes) { var i; var num; var nbytes, nbits, bytecnt, tmp; var bytes = new Array(32); nbytes = (1 >>> 0); bytes[0] = (1 >>> 0); nbits = 0; for (i = 0; i < nints; i++) { tmp = 0; for (bytecnt = 0; bytecnt < nbytes; bytecnt++) { tmp = (bytes[bytecnt] >>> 0) * (sizes[i] >>> 0) + (tmp >>> 0); bytes[bytecnt] = (tmp >>> 0) & 0xff; tmp >>= 8; } while (tmp != 0) { bytes[bytecnt++] = (tmp >>> 0) & 0xff; tmp >>= 8; } nbytes = (bytecnt >>> 0); } num = 1; nbytes--; while (bytes[nbytes] >= num) { nbits++; num *= 2; } return nbits + nbytes * 8; } calculatecoords(buffer, buf) { var thiscoord = new Array(3); var prevcoord = new Array(3); var lfp = []; var cntcoor = 0; var j = 0; var tmp=0; buf[3] = buffer.slice(0, buf[0]); buf[0] = buf[1] = buf[2] = 0; //lfp = fp; this.inv_precision = 1.0 / (this.precision); var run = 0; var i = 0; var lip = null; this.numframe++; //thiscoord[0] = xtc_receivebits(buf, bitsizeint[0]); while (i < this.lsize) { //thiscoord=lip+i*3; if (this.bitsize == 0) { // hd: in this case this code will be never loaded thiscoord[0] = this.xtc_receivebits(buf, bitsizeint[0]); thiscoord[1] = this.xtc_receivebits(buf, bitsizeint[1]); thiscoord[2] = this.xtc_receivebits(buf, bitsizeint[2]); } else { this.xtc_receiveints(buf, 3, this.bitsize, this.sizeint, thiscoord); } i++; thiscoord[0] += this.minint[0]; thiscoord[1] += this.minint[1]; thiscoord[2] += this.minint[2]; prevcoord[0] = thiscoord[0]; prevcoord[1] = thiscoord[1]; prevcoord[2] = thiscoord[2]; this.flag = this.xtc_receivebits(buf, 1); this.is_smaller = 0; if (this.flag == 1) { run = this.xtc_receivebits(buf, 5); this.is_smaller = run % 3; run -= this.is_smaller; this.is_smaller--; } if (run > 0) { //thiscoord += 3; // HD note: just effects that all elements in the array thiscoord gets the value 0 for (var k = 0; k < run; k += 3) { this.xtc_receiveints(buf, 3, this.smallidx, this.sizesmall, thiscoord); i++; thiscoord[0] += prevcoord[0] - this.small; thiscoord[1] += prevcoord[1] - this.small; thiscoord[2] += prevcoord[2] - this.small; if (k == 0) { // interchange first with second atom for better // compression of water molecules // tmp = thiscoord[0]; thiscoord[0] = prevcoord[0]; prevcoord[0] = tmp; tmp = thiscoord[1]; thiscoord[1] = prevcoord[1]; prevcoord[1] = tmp; tmp = thiscoord[2]; thiscoord[2] = prevcoord[2]; prevcoord[2] = tmp; lfp[cntcoor] = prevcoord[0] * this.inv_precision; lfp[cntcoor + 1] = prevcoord[1] * this.inv_precision; lfp[cntcoor + 2] = prevcoord[2] * this.inv_precision; cntcoor += 3; } else { prevcoord[0] = thiscoord[0]; prevcoord[1] = thiscoord[1]; prevcoord[2] = thiscoord[2]; } lfp[cntcoor] = thiscoord[0] * this.inv_precision; lfp[cntcoor + 1] = thiscoord[1] * this.inv_precision; lfp[cntcoor + 2] = thiscoord[2] * this.inv_precision; cntcoor += 3; } // loop for } else { lfp[cntcoor] = thiscoord[0] * this.inv_precision; lfp[cntcoor + 1] = thiscoord[1] * this.inv_precision; lfp[cntcoor + 2] = thiscoord[2] * this.inv_precision; cntcoor += 3; } this.smallidx += this.is_smaller; if (this.is_smaller < 0) { this.small = this.smallerer; if (this.smallidx > this.FIRSTIDX) { this.smallerer = this.xtc_magicints[this.smallidx - 1] / 2; } else { this.smallerer = 0; } } else if (this.is_smaller > 0) { this.smallerer = this.small; this.small = this.xtc_magicints[this.smallidx] / 2; } this.sizesmall[0] = this.sizesmall[1] = this.sizesmall[2] = this.xtc_magicints[this.smallidx]; } //Scale for (var n = 0; n < this.natoms * 3; n++) { lfp[n] *= this.ANGS_PER_NM; } var row = 1; var counter = 0; //atom=main.Obj3D.molecule.GetAtoms()[counter]; do { if (row > 3) { row = 1; counter++; //atom=main.Obj3D.molecule.GetAtoms()[counter]; } //var floatTmp = lfp[j]/ANGS_PER_NM; if (row == 1) { this.arreglo[this.iarr] = lfp[j]; this.iarr++; } else if (row == 2) { this.arreglo1[this.iarr1] = lfp[j]; this.iarr1++; } else if (row == 3) { this.arreglo2[this.iarr2] = lfp[j]; this.iarr2++; } if (this.iarr2 == this.arreglo2.length) { this.iarr2 = 0, this.iarr1 = 0, this.iarr = 0; self.postMessage({ cmd: "enviar", dato: this.arreglo, dato1: this.arreglo1, dato2: this.arreglo2, bndarray: this.bnd }); } row++; j++; } while (j < this.natoms * 3); // console.log(buffer.byteLength + " " + buf[3].byteLength); if (buffer.byteLength >= buf[3].byteLength + 9) { for (i = 0; i < 5; i++) { if (buffer.byteLength > buf[3].byteLength + i) { if (new DataView(buffer).getInt32(buf[3].byteLength + i) != 1995) {} else { break; } } } this.part = buffer.slice(buf[3].byteLength + i); } else if (this.trans < this.tam) { this.part = buffer.slice(buf[3].byteLength); this.bndrev = true; } //console.log("HTMoL3: "+this.part.byteLength); if (this.part.byteLength >= 92) { var nextbuf = new DataView(this.part).getInt32(88); if (this.part.byteLength >= 92 + nextbuf) { //console.log("pasa"); this.readhead(this.part); } } } xtc_receivebits(buf, nbits) { var cnt, num; var lastbits, lastbyte, tmplast; var cbuf; var mask = (1 << nbits) - 1; cbuf = buf[3]; cnt = buf[0]; lastbits = (buf[1] >>> 0); lastbyte = (buf[2] >>> 0); num = 0; while (nbits >= 8) { var minum = this.getInt8(cnt, cbuf); lastbyte = ((lastbyte >>> 0) << 8) | (minum >>> 0); cnt += 8; num |= ((lastbyte >>> 0) >> (lastbits >>> 0)) << (nbits - 8); nbits -= 8; } if (nbits > 0) { if (lastbits < (nbits >>> 0)) { lastbits += 8; minum = this.getInt8(cnt, cbuf); lastbyte = ((lastbyte >>> 0) << 8) | (minum >>> 0); cnt += 8; } lastbits -= nbits; num |= ((lastbyte >>> 0) >> (lastbits >>> 0)) & ((1 << nbits) - 1); } num &= mask; buf[0] = cnt; buf[1] = (lastbits >>> 0); buf[2] = (lastbyte >>> 0); return num; } xtc_receiveints(buf, nints, nbits, sizes, nums) { var bytes = new Array(32); var i, j, nbytes, p, num; bytes[1] = bytes[2] = bytes[3] = 0; nbytes = 0; i = 0; do { bytes[i] = 0; i++; } while (i < 32); while (nbits > 8) { bytes[nbytes] = parseInt(this.xtc_receivebits(buf, 8)); nbytes++; nbits -= 8; } if (nbits > 0) { bytes[nbytes] = parseInt(this.xtc_receivebits(buf, nbits)); nbytes++; } for (i = nints - 1; i > 0; i--) { num = 0; for (j = nbytes - 1; j >= 0; j--) { num = (num << 8) | bytes[j]; p = parseInt(num / (sizes[i] >>> 0)); bytes[j] = p; num = num - p * (sizes[i] >>> 0); } nums[i] = num; } nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); } getInt8(idx, buf) { var buffer = buf; var u8 = new Uint8Array(buf); var bidx = idx / 8 | 0; var a = u8[bidx]; return a; } }