molstar
Version:
A comprehensive macromolecular library.
188 lines • 8.79 kB
JavaScript
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = exports.parseFile = exports.getDsn6Counts = exports.parseDsn6Values = exports.readDsn6Header = exports.dsn6HeaderSize = void 0;
var tslib_1 = require("tslib");
var mol_task_1 = require("../../../mol-task");
var result_1 = require("../result");
var file_handle_1 = require("../../common/file-handle");
var simple_buffer_1 = require("../../../mol-io/common/simple-buffer");
exports.dsn6HeaderSize = 512;
function parseBrixHeader(str) {
return {
xStart: parseInt(str.substr(10, 5)),
yStart: parseInt(str.substr(15, 5)),
zStart: parseInt(str.substr(20, 5)),
xExtent: parseInt(str.substr(32, 5)),
yExtent: parseInt(str.substr(38, 5)),
zExtent: parseInt(str.substr(42, 5)),
xRate: parseInt(str.substr(52, 5)),
yRate: parseInt(str.substr(58, 5)),
zRate: parseInt(str.substr(62, 5)),
xlen: parseFloat(str.substr(73, 10)),
ylen: parseFloat(str.substr(83, 10)),
zlen: parseFloat(str.substr(93, 10)),
alpha: parseFloat(str.substr(103, 10)),
beta: parseFloat(str.substr(113, 10)),
gamma: parseFloat(str.substr(123, 10)),
divisor: parseFloat(str.substr(138, 12)),
summand: parseInt(str.substr(155, 8)),
sigma: parseFloat(str.substr(170, 12))
};
}
function parseDsn6Header(buffer, littleEndian) {
var readInt = littleEndian ? function (o) { return buffer.readInt16LE(o * 2); } : function (o) { return buffer.readInt16BE(o * 2); };
var factor = 1 / readInt(17);
return {
xStart: readInt(0),
yStart: readInt(1),
zStart: readInt(2),
xExtent: readInt(3),
yExtent: readInt(4),
zExtent: readInt(5),
xRate: readInt(6),
yRate: readInt(7),
zRate: readInt(8),
xlen: readInt(9) * factor,
ylen: readInt(10) * factor,
zlen: readInt(11) * factor,
alpha: readInt(12) * factor,
beta: readInt(13) * factor,
gamma: readInt(14) * factor,
divisor: readInt(15) / 100,
summand: readInt(16),
sigma: undefined
};
}
function getBlocks(header) {
var xExtent = header.xExtent, yExtent = header.yExtent, zExtent = header.zExtent;
var xBlocks = Math.ceil(xExtent / 8);
var yBlocks = Math.ceil(yExtent / 8);
var zBlocks = Math.ceil(zExtent / 8);
return { xBlocks: xBlocks, yBlocks: yBlocks, zBlocks: zBlocks };
}
function readDsn6Header(file) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var buffer, brixStr, isBrix, littleEndian, header;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, file.readBuffer(0, exports.dsn6HeaderSize)];
case 1:
buffer = (_a.sent()).buffer;
brixStr = String.fromCharCode.apply(null, buffer);
isBrix = brixStr.startsWith(':-)');
littleEndian = isBrix || buffer.readInt16LE(18 * 2) === 100;
header = isBrix ? parseBrixHeader(brixStr) : parseDsn6Header(buffer, littleEndian);
return [2 /*return*/, { header: header, littleEndian: littleEndian }];
}
});
});
}
exports.readDsn6Header = readDsn6Header;
function parseDsn6Values(header, source, target, littleEndian) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var divisor, summand, xExtent, yExtent, zExtent, _a, xBlocks, yBlocks, zBlocks, offset, zz, yy, xx, k, z, j, y, i, x, idx;
return (0, tslib_1.__generator)(this, function (_b) {
if (!littleEndian) {
// even though the values are one byte they need to be swapped like they are 2
simple_buffer_1.SimpleBuffer.flipByteOrderInPlace2(source.buffer);
}
divisor = header.divisor, summand = header.summand, xExtent = header.xExtent, yExtent = header.yExtent, zExtent = header.zExtent;
_a = getBlocks(header), xBlocks = _a.xBlocks, yBlocks = _a.yBlocks, zBlocks = _a.zBlocks;
offset = 0;
// loop over blocks
for (zz = 0; zz < zBlocks; ++zz) {
for (yy = 0; yy < yBlocks; ++yy) {
for (xx = 0; xx < xBlocks; ++xx) {
// loop inside block
for (k = 0; k < 8; ++k) {
z = 8 * zz + k;
for (j = 0; j < 8; ++j) {
y = 8 * yy + j;
for (i = 0; i < 8; ++i) {
x = 8 * xx + i;
// check if remaining slice-part contains values
if (x < xExtent && y < yExtent && z < zExtent) {
idx = ((((x * yExtent) + y) * zExtent) + z);
target[idx] = (source[offset] - summand) / divisor;
++offset;
}
else {
offset += 8 - i;
break;
}
}
}
}
}
}
}
return [2 /*return*/];
});
});
}
exports.parseDsn6Values = parseDsn6Values;
function getDsn6Counts(header) {
var xExtent = header.xExtent, yExtent = header.yExtent, zExtent = header.zExtent;
var _a = getBlocks(header), xBlocks = _a.xBlocks, yBlocks = _a.yBlocks, zBlocks = _a.zBlocks;
var valueCount = xExtent * yExtent * zExtent;
var count = xBlocks * 8 * yBlocks * 8 * zBlocks * 8;
var elementByteSize = 1;
var byteCount = count * elementByteSize;
return { count: count, byteCount: byteCount, valueCount: valueCount };
}
exports.getDsn6Counts = getDsn6Counts;
function parseInternal(file, size, ctx) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var _a, header, littleEndian, buffer, valueCount, values, result;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, ctx.update({ message: 'Parsing DSN6/BRIX file...' })];
case 1:
_b.sent();
return [4 /*yield*/, readDsn6Header(file)];
case 2:
_a = _b.sent(), header = _a.header, littleEndian = _a.littleEndian;
return [4 /*yield*/, file.readBuffer(exports.dsn6HeaderSize, size - exports.dsn6HeaderSize)];
case 3:
buffer = (_b.sent()).buffer;
valueCount = getDsn6Counts(header).valueCount;
values = new Float32Array(valueCount);
return [4 /*yield*/, parseDsn6Values(header, buffer, values, littleEndian)];
case 4:
_b.sent();
result = { header: header, values: values, name: file.name };
return [2 /*return*/, result];
}
});
});
}
function parseFile(file, size) {
var _this = this;
return mol_task_1.Task.create('Parse DSN6/BRIX', function (ctx) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
var _a, _b, e_1;
return (0, tslib_1.__generator)(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 2, , 3]);
_b = (_a = result_1.ReaderResult).success;
return [4 /*yield*/, parseInternal(file, size, ctx)];
case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
case 2:
e_1 = _c.sent();
return [2 /*return*/, result_1.ReaderResult.error(e_1)];
case 3: return [2 /*return*/];
}
});
}); });
}
exports.parseFile = parseFile;
function parse(buffer, name) {
return parseFile(file_handle_1.FileHandle.fromBuffer(simple_buffer_1.SimpleBuffer.fromUint8Array(buffer), name), buffer.length);
}
exports.parse = parse;
//# sourceMappingURL=parser.js.map
;