molstar
Version:
A comprehensive macromolecular library.
204 lines (200 loc) • 9.2 kB
JavaScript
"use strict";
/**
* Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMol = exports.handlePropertiesBlock = exports.handleFormalCharges = exports.handleBonds = exports.handleAtoms = exports.formalChargeMapper = void 0;
var tslib_1 = require("tslib");
var db_1 = require("../../../mol-data/db");
var mol_task_1 = require("../../../mol-task");
var token_1 = require("../common/text/column/token");
var tokenizer_1 = require("../common/text/tokenizer");
var result_1 = require("../result");
/*
The atom lines in a .mol file have the following structure:
xxxxx.xxxxyyyyy.yyyyzzzzz.zzzz aaaddcccssshhhbbbvvvHHHrrriiimmmnnneee
---------------------------------------------------------------------
Below is a breakdown of each component and its start/end indices:
xxxxx.xxxx (X COORDINATE, 1-10)
yyyyy.yyyy (Y COORDINATE, 10-20)
zzzzz.zzzz (Z COORDINATE, 20-30)
_ (30 IS EMPTY)
aaa (ATOM SYMBOL, 31-34)
dd (MASS DIFF, 34-36)
ccc (FORMAL CHARGE, 36-39)
sss (ATOM STEREO PARITY, 39-42)
hhh (HYDROGEN COUNT+1, 42-45)
bbb (STEREO CARE BOX, 45-48)
vvv (VALENCE, 48-51)
HHH (H0 DESIGNATOR, 51-54)
rrr (UNUSED, 54-57)
iii (UNUSED, 57-60)
mmm (ATOM-ATOM MAPPING NUMBER, 60-63)
nnn (INVERSION/RETENTION FLAG, 63-66)
eee (EXACT CHANGE FLAG, 66-69)
*/
/**
* @param key - The value found at the atom block.
* @returns The actual formal charge based on the mapping.
*/
function formalChargeMapper(key) {
switch (key) {
case 7: return -3;
case 6: return -2;
case 5: return -1;
case 0: return 0;
case 3: return 1;
case 2: return 2;
case 1: return 3;
case 4: return 0;
default:
console.error("Value ".concat(key, " is outside the 0-7 range, defaulting to 0."));
return 0;
}
}
exports.formalChargeMapper = formalChargeMapper;
function handleAtoms(tokenizer, count) {
var x = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var y = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var z = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var type_symbol = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var formal_charge = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
for (var i = 0; i < count; ++i) {
tokenizer_1.Tokenizer.markLine(tokenizer);
var s = tokenizer.tokenStart, position = tokenizer.position;
tokenizer_1.Tokenizer.trim(tokenizer, s, s + 10);
tokenizer_1.TokenBuilder.addUnchecked(x, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 10, s + 20);
tokenizer_1.TokenBuilder.addUnchecked(y, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 20, s + 30);
tokenizer_1.TokenBuilder.addUnchecked(z, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 31, s + 34);
tokenizer_1.TokenBuilder.addUnchecked(type_symbol, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 36, s + 39);
tokenizer_1.TokenBuilder.addUnchecked(formal_charge, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer.position = position;
}
return {
count: count,
x: (0, token_1.TokenColumnProvider)(x)(db_1.Column.Schema.float),
y: (0, token_1.TokenColumnProvider)(y)(db_1.Column.Schema.float),
z: (0, token_1.TokenColumnProvider)(z)(db_1.Column.Schema.float),
type_symbol: (0, token_1.TokenColumnProvider)(type_symbol)(db_1.Column.Schema.str),
formal_charge: (0, token_1.TokenColumnProvider)(formal_charge)(db_1.Column.Schema.int)
};
}
exports.handleAtoms = handleAtoms;
function handleBonds(tokenizer, count) {
var atomIdxA = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var atomIdxB = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
var order = tokenizer_1.TokenBuilder.create(tokenizer.data, count * 2);
for (var i = 0; i < count; ++i) {
tokenizer_1.Tokenizer.markLine(tokenizer);
var s = tokenizer.tokenStart, position = tokenizer.position;
tokenizer_1.Tokenizer.trim(tokenizer, s, s + 3);
tokenizer_1.TokenBuilder.addUnchecked(atomIdxA, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 3, s + 6);
tokenizer_1.TokenBuilder.addUnchecked(atomIdxB, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer_1.Tokenizer.trim(tokenizer, s + 6, s + 9);
tokenizer_1.TokenBuilder.addUnchecked(order, tokenizer.tokenStart, tokenizer.tokenEnd);
tokenizer.position = position;
}
return {
count: count,
atomIdxA: (0, token_1.TokenColumnProvider)(atomIdxA)(db_1.Column.Schema.int),
atomIdxB: (0, token_1.TokenColumnProvider)(atomIdxB)(db_1.Column.Schema.int),
order: (0, token_1.TokenColumnProvider)(order)(db_1.Column.Schema.int)
};
}
exports.handleBonds = handleBonds;
function handleFormalCharges(tokenizer, lineStart, formalCharges) {
tokenizer_1.Tokenizer.trim(tokenizer, lineStart + 6, lineStart + 9);
var numOfCharges = parseInt(tokenizer_1.Tokenizer.getTokenString(tokenizer));
for (var i = 0; i < numOfCharges; ++i) {
/*
M CHG 3 1 -1 2 0 2 -1
| | | | |
| | | | |__charge2 (etc.)
| | | |
| | | |__atomIdx2
| | |
| | |__charge1
| |
| |__atomIdx1 (cursor at position 12)
|
|___numOfCharges
*/
var offset = 9 + (i * 8);
tokenizer_1.Tokenizer.trim(tokenizer, lineStart + offset, lineStart + offset + 4);
var _atomIdx = tokenizer_1.Tokenizer.getTokenString(tokenizer);
formalCharges.atomIdx.push(+_atomIdx);
tokenizer_1.Tokenizer.trim(tokenizer, lineStart + offset + 4, lineStart + offset + 8);
var _charge = tokenizer_1.Tokenizer.getTokenString(tokenizer);
formalCharges.charge.push(+_charge);
}
/* Once the line is read, move to the next one. */
tokenizer_1.Tokenizer.eatLine(tokenizer);
}
exports.handleFormalCharges = handleFormalCharges;
/** Call an appropriate handler based on the property type.
* (For now it only calls the formal charge handler, additional handlers can
* be added for other properties.)
*/
function handlePropertiesBlock(tokenizer) {
var _atomIdx = [];
var _charge = [];
var _formalCharges = { atomIdx: _atomIdx, charge: _charge };
while (tokenizer.position < tokenizer.length) {
var s = tokenizer.position;
tokenizer_1.Tokenizer.trim(tokenizer, s + 3, s + 6);
var propertyType = tokenizer_1.Tokenizer.getTokenString(tokenizer);
if (propertyType === 'END')
break;
tokenizer_1.Tokenizer.eatLine(tokenizer);
switch (propertyType) {
case 'CHG':
handleFormalCharges(tokenizer, s, _formalCharges);
break;
default:
break;
}
}
var formalCharges = {
atomIdx: db_1.Column.ofIntArray(_formalCharges.atomIdx),
charge: db_1.Column.ofIntArray(_formalCharges.charge)
};
return formalCharges;
}
exports.handlePropertiesBlock = handlePropertiesBlock;
function parseInternal(data) {
var tokenizer = (0, tokenizer_1.Tokenizer)(data);
var title = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
var program = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
var comment = tokenizer_1.Tokenizer.readLine(tokenizer).trim();
var counts = tokenizer_1.Tokenizer.readLine(tokenizer);
var atomCount = +counts.substr(0, 3), bondCount = +counts.substr(3, 3);
var atoms = handleAtoms(tokenizer, atomCount);
var bonds = handleBonds(tokenizer, bondCount);
var formalCharges = handlePropertiesBlock(tokenizer);
var result = {
title: title,
program: program,
comment: comment,
atoms: atoms,
bonds: bonds,
formalCharges: formalCharges,
};
return result_1.ReaderResult.success(result);
}
function parseMol(data) {
var _this = this;
return mol_task_1.Task.create('Parse Mol', function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, parseInternal(data)];
});
}); });
}
exports.parseMol = parseMol;