UNPKG

molstar

Version:

A comprehensive macromolecular library.

278 lines 14.9 kB
/** * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { __awaiter, __generator } from "tslib"; import { Task, chunkedSubtask } from '../../../mol-task'; import { Tokenizer, TokenBuilder } from '../common/text/tokenizer'; import { ReaderResult as Result } from '../result'; import { TokenColumnProvider as TokenColumn } from '../common/text/column/token'; import { Column } from '../../../mol-data/db'; var readLine = Tokenizer.readLine, skipWhitespace = Tokenizer.skipWhitespace, eatValue = Tokenizer.eatValue, eatLine = Tokenizer.eatLine, markStart = Tokenizer.markStart; var reWhitespace = /\s+/; var reTitle = /(^\*|REMARK)*/; function State(tokenizer, runtimeCtx) { return { tokenizer: tokenizer, runtimeCtx: runtimeCtx, }; } function handleAtoms(state, count) { return __awaiter(this, void 0, void 0, function () { var tokenizer, atomId, segmentName, residueId, residueName, atomName, atomType, charge, mass, position, line, isLammpsFull, n, length, linesAlreadyRead; return __generator(this, function (_a) { switch (_a.label) { case 0: tokenizer = state.tokenizer; atomId = TokenBuilder.create(tokenizer.data, count * 2); segmentName = TokenBuilder.create(tokenizer.data, count * 2); residueId = TokenBuilder.create(tokenizer.data, count * 2); residueName = TokenBuilder.create(tokenizer.data, count * 2); atomName = TokenBuilder.create(tokenizer.data, count * 2); atomType = TokenBuilder.create(tokenizer.data, count * 2); charge = TokenBuilder.create(tokenizer.data, count * 2); mass = TokenBuilder.create(tokenizer.data, count * 2); position = tokenizer.position; line = readLine(tokenizer).trim(); tokenizer.position = position; isLammpsFull = line.split(reWhitespace).length === 7; n = isLammpsFull ? 6 : 8; length = tokenizer.length; linesAlreadyRead = 0; return [4 /*yield*/, chunkedSubtask(state.runtimeCtx, 100000, void 0, function (chunkSize) { var linesToRead = Math.min(count - linesAlreadyRead, chunkSize); for (var i = 0; i < linesToRead; ++i) { for (var j = 0; j < n; ++j) { skipWhitespace(tokenizer); markStart(tokenizer); eatValue(tokenizer); if (isLammpsFull) { switch (j) { case 0: TokenBuilder.addUnchecked(atomId, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 1: TokenBuilder.addUnchecked(residueId, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 2: TokenBuilder.addUnchecked(atomName, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 3: TokenBuilder.addUnchecked(atomType, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 4: TokenBuilder.addUnchecked(charge, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 5: TokenBuilder.addUnchecked(mass, tokenizer.tokenStart, tokenizer.tokenEnd); break; } } else { switch (j) { case 0: TokenBuilder.addUnchecked(atomId, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 1: TokenBuilder.addUnchecked(segmentName, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 2: TokenBuilder.addUnchecked(residueId, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 3: TokenBuilder.addUnchecked(residueName, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 4: TokenBuilder.addUnchecked(atomName, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 5: TokenBuilder.addUnchecked(atomType, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 6: TokenBuilder.addUnchecked(charge, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 7: TokenBuilder.addUnchecked(mass, tokenizer.tokenStart, tokenizer.tokenEnd); break; } } } // ignore any extra columns eatLine(tokenizer); markStart(tokenizer); } linesAlreadyRead += linesToRead; return linesToRead; }, function (ctx) { return ctx.update({ message: 'Parsing...', current: tokenizer.position, max: length }); })]; case 1: _a.sent(); return [2 /*return*/, { count: count, atomId: TokenColumn(atomId)(Column.Schema.int), segmentName: isLammpsFull ? TokenColumn(residueId)(Column.Schema.str) : TokenColumn(segmentName)(Column.Schema.str), residueId: TokenColumn(residueId)(Column.Schema.int), residueName: isLammpsFull ? TokenColumn(residueId)(Column.Schema.str) : TokenColumn(residueName)(Column.Schema.str), atomName: TokenColumn(atomName)(Column.Schema.str), atomType: TokenColumn(atomType)(Column.Schema.str), charge: TokenColumn(charge)(Column.Schema.float), mass: TokenColumn(mass)(Column.Schema.float) }]; } }); }); } function handleBonds(state, count) { return __awaiter(this, void 0, void 0, function () { var tokenizer, atomIdA, atomIdB, length, bondsAlreadyRead; return __generator(this, function (_a) { switch (_a.label) { case 0: tokenizer = state.tokenizer; atomIdA = TokenBuilder.create(tokenizer.data, count * 2); atomIdB = TokenBuilder.create(tokenizer.data, count * 2); length = tokenizer.length; bondsAlreadyRead = 0; return [4 /*yield*/, chunkedSubtask(state.runtimeCtx, 10, void 0, function (chunkSize) { var bondsToRead = Math.min(count - bondsAlreadyRead, chunkSize); for (var i = 0; i < bondsToRead; ++i) { for (var j = 0; j < 2; ++j) { skipWhitespace(tokenizer); markStart(tokenizer); eatValue(tokenizer); switch (j) { case 0: TokenBuilder.addUnchecked(atomIdA, tokenizer.tokenStart, tokenizer.tokenEnd); break; case 1: TokenBuilder.addUnchecked(atomIdB, tokenizer.tokenStart, tokenizer.tokenEnd); break; } } } bondsAlreadyRead += bondsToRead; return bondsToRead; }, function (ctx) { return ctx.update({ message: 'Parsing...', current: tokenizer.position, max: length }); })]; case 1: _a.sent(); return [2 /*return*/, { count: count, atomIdA: TokenColumn(atomIdA)(Column.Schema.int), atomIdB: TokenColumn(atomIdB)(Column.Schema.int), }]; } }); }); } function parseTitle(state, count) { var title = []; for (var i = 0; i < count; ++i) { var line = readLine(state.tokenizer); title.push(line.replace(reTitle, '').trim()); } return title; } function parseInternal(data, ctx) { return __awaiter(this, void 0, void 0, function () { var tokenizer, state, title, atoms, bonds, id, line, numTitle, numAtoms, numBonds, result; return __generator(this, function (_a) { switch (_a.label) { case 0: tokenizer = Tokenizer(data); state = State(tokenizer, ctx); title = undefined; atoms = undefined; bonds = undefined; id = readLine(state.tokenizer).trim(); _a.label = 1; case 1: if (!(tokenizer.tokenEnd < tokenizer.length)) return [3 /*break*/, 8]; line = readLine(state.tokenizer).trim(); if (!line.includes('!NTITLE')) return [3 /*break*/, 2]; numTitle = parseInt(line.split(reWhitespace)[0]); title = parseTitle(state, numTitle); return [3 /*break*/, 7]; case 2: if (!line.includes('!NATOM')) return [3 /*break*/, 4]; numAtoms = parseInt(line.split(reWhitespace)[0]); return [4 /*yield*/, handleAtoms(state, numAtoms)]; case 3: atoms = _a.sent(); return [3 /*break*/, 7]; case 4: if (!line.includes('!NBOND')) return [3 /*break*/, 6]; numBonds = parseInt(line.split(reWhitespace)[0]); return [4 /*yield*/, handleBonds(state, numBonds)]; case 5: bonds = _a.sent(); return [3 /*break*/, 8]; // TODO: don't break when the below are implemented case 6: if (line.includes('!NTHETA')) { // TODO } else if (line.includes('!NPHI')) { // TODO } else if (line.includes('!NIMPHI')) { // TODO } else if (line.includes('!NDON')) { // TODO } else if (line.includes('!NACC')) { // TODO } else if (line.includes('!NNB')) { // TODO } else if (line.includes('!NGRP NST2')) { // TODO } else if (line.includes('!MOLNT')) { // TODO } else if (line.includes('!NUMLP NUMLPH')) { // TODO } else if (line.includes('!NCRTERM')) { // TODO } _a.label = 7; case 7: return [3 /*break*/, 1]; case 8: if (title === undefined) { title = []; } if (atoms === undefined) { return [2 /*return*/, Result.error('no atoms data')]; } if (bonds === undefined) { return [2 /*return*/, Result.error('no bonds data')]; } result = { id: id, title: title, atoms: atoms, bonds: bonds }; return [2 /*return*/, Result.success(result)]; } }); }); } export function parsePsf(data) { var _this = this; return Task.create('Parse PSF', function (ctx) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, parseInternal(data, ctx)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }); } //# sourceMappingURL=parser.js.map