molstar
Version:
A comprehensive macromolecular library.
136 lines (135 loc) • 4.71 kB
JavaScript
/**
* Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Adapted from NGL.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseTrr = parseTrr;
const mol_task_1 = require("../../../mol-task");
const result_1 = require("../result");
async function parseInternal(data) {
// https://github.com/gromacs/gromacs/blob/master/src/gromacs/fileio/trrio.cpp
const dv = new DataView(data.buffer);
const f = {
frames: [],
boxes: [],
times: [],
timeOffset: 0,
deltaTime: 0
};
const coordinates = f.frames;
const boxes = f.boxes;
const times = f.times;
let offset = 0;
while (true) {
// const magicnum = dv.getInt32(offset)
// const i1 = dv.getFloat32(offset + 4)
offset += 8;
const versionSize = dv.getInt32(offset);
offset += 4;
offset += versionSize;
// const irSize = dv.getInt32(offset)
// const eSize = dv.getInt32(offset + 4)
const boxSize = dv.getInt32(offset + 8);
const virSize = dv.getInt32(offset + 12);
const presSize = dv.getInt32(offset + 16);
// const topSize = dv.getInt32(offset + 20)
// const symSize = dv.getInt32(offset + 24)
const coordSize = dv.getInt32(offset + 28);
const velocitySize = dv.getInt32(offset + 32);
const forceSize = dv.getInt32(offset + 36);
const natoms = dv.getInt32(offset + 40);
// const step = dv.getInt32(offset + 44)
// const nre = dv.getInt32(offset + 48)
offset += 52;
const floatSize = boxSize / 9;
const natoms3 = natoms * 3;
// let lambda
if (floatSize === 8) {
times.push(dv.getFloat64(offset));
// lambda = dv.getFloat64(offset + 8)
}
else {
times.push(dv.getFloat32(offset));
// lambda = dv.getFloat32(offset + 4)
}
offset += 2 * floatSize;
if (boxSize) {
const box = new Float32Array(9);
if (floatSize === 8) {
for (let i = 0; i < 9; ++i) {
box[i] = dv.getFloat64(offset) * 10;
offset += 8;
}
}
else {
for (let i = 0; i < 9; ++i) {
box[i] = dv.getFloat32(offset) * 10;
offset += 4;
}
}
boxes.push(box);
}
// ignore, unused
offset += virSize;
// ignore, unused
offset += presSize;
if (coordSize) {
const x = new Float32Array(natoms);
const y = new Float32Array(natoms);
const z = new Float32Array(natoms);
if (floatSize === 8) {
for (let i = 0; i < natoms; ++i) {
x[i] = dv.getFloat64(offset) * 10;
y[i] = dv.getFloat64(offset + 8) * 10;
z[i] = dv.getFloat64(offset + 16) * 10;
offset += 24;
}
}
else {
const tmp = new Uint32Array(data.buffer, offset, natoms3);
for (let i = 0; i < natoms3; ++i) {
const value = tmp[i];
tmp[i] = (((value & 0xFF) << 24) | ((value & 0xFF00) << 8) |
((value >> 8) & 0xFF00) | ((value >> 24) & 0xFF));
}
const frameCoords = new Float32Array(data.buffer, offset, natoms3);
for (let i = 0; i < natoms; ++i) {
x[i] = frameCoords[i * 3] * 10;
y[i] = frameCoords[i * 3 + 1] * 10;
z[i] = frameCoords[i * 3 + 2] * 10;
offset += 12;
}
}
coordinates.push({ count: natoms, x, y, z });
}
// ignore, unused
offset += velocitySize;
// ignore, unused
offset += forceSize;
if (offset >= data.byteLength)
break;
}
if (times.length >= 1) {
f.timeOffset = times[0];
}
if (times.length >= 2) {
f.deltaTime = times[1] - times[0];
}
return f;
}
function parseTrr(data) {
return mol_task_1.Task.create('Parse TRR', async (ctx) => {
try {
ctx.update({ canAbort: true, message: 'Parsing trajectory...' });
const file = await parseInternal(data);
return result_1.ReaderResult.success(file);
}
catch (e) {
return result_1.ReaderResult.error('' + e);
}
});
}
;