123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- /*
- * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
- *
- * from https://github.com/dsehnal/CIFTools.js
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- /**
- * Efficient integer and float parsers.
- *
- * For the purposes of parsing numbers from the mmCIF data representations,
- * up to 4 times faster than JS parseInt/parseFloat.
- */
- function parseInt(str, start, end) {
- var ret = 0, neg = 1;
- if (str.charCodeAt(start) === 45 /* - */) {
- neg = -1;
- start++;
- }
- for (; start < end; start++) {
- var c = str.charCodeAt(start) - 48;
- if (c > 9 || c < 0)
- { return (neg * ret) | 0; }
- else
- { ret = (10 * ret + c) | 0; }
- }
- return neg * ret;
- }
- function parseScientific(main, str, start, end) {
- // handle + in '1e+1' separately.
- if (str.charCodeAt(start) === 43 /* + */)
- { start++; }
- return main * Math.pow(10.0, parseInt(str, start, end));
- }
- function parseFloat(str, start, end) {
- var neg = 1.0, ret = 0.0, point = 0.0, div = 1.0;
- if (str.charCodeAt(start) === 45) {
- neg = -1.0;
- ++start;
- }
- while (start < end) {
- var c = str.charCodeAt(start) - 48;
- if (c >= 0 && c < 10) {
- ret = ret * 10 + c;
- ++start;
- }
- else if (c === -2) {
- ++start;
- while (start < end) {
- c = str.charCodeAt(start) - 48;
- if (c >= 0 && c < 10) {
- point = 10.0 * point + c;
- div = 10.0 * div;
- ++start;
- }
- else if (c === 53 || c === 21) {
- return parseScientific(neg * (ret + point / div), str, start + 1, end);
- }
- else {
- return neg * (ret + point / div);
- }
- }
- return neg * (ret + point / div);
- }
- else if (c === 53 || c === 21) {
- return parseScientific(neg * ret, str, start + 1, end);
- }
- else
- { break; }
- }
- return neg * ret;
- }
- /**
- * Eat everything until a newline occurs.
- */
- function eatLine(state) {
- while (state.position < state.length) {
- switch (state.data.charCodeAt(state.position)) {
- case 10:// \n
- state.currentTokenEnd = state.position;
- ++state.position;
- ++state.currentLineNumber;
- return;
- case 13:// \r
- state.currentTokenEnd = state.position;
- ++state.position;
- ++state.currentLineNumber;
- if (state.data.charCodeAt(state.position) === 10) {
- ++state.position;
- }
- return;
- default:
- ++state.position;
- }
- }
- state.currentTokenEnd = state.position;
- }
- /**
- * Eat everything until a whitespace/newline occurs.
- */
- function eatValue(state) {
- while (state.position < state.length) {
- switch (state.data.charCodeAt(state.position)) {
- case 9: // \t
- case 10: // \n
- case 13: // \r
- case 32:// ' '
- state.currentTokenEnd = state.position;
- return;
- default:
- ++state.position;
- break;
- }
- }
- state.currentTokenEnd = state.position;
- }
- /**
- * Skips all the whitespace - space, tab, newline, CR
- * Handles incrementing line count.
- */
- function skipWhitespace(state) {
- var prev = 10;
- while (state.position < state.length) {
- var c = state.data.charCodeAt(state.position);
- switch (c) {
- case 9: // '\t'
- case 32:// ' '
- prev = c;
- ++state.position;
- break;
- case 10:// \n
- // handle \r\n
- if (prev !== 13) {
- ++state.currentLineNumber;
- }
- prev = c;
- ++state.position;
- break;
- case 13:// \r
- prev = c;
- ++state.position;
- ++state.currentLineNumber;
- break;
- default:
- return prev;
- }
- }
- return prev;
- }
- var Tokens;
- (function (Tokens) {
- function resize(tokens) {
- // scale the size using golden ratio, because why not.
- var newBuffer = new Int32Array((1.61 * tokens.indices.length) | 0);
- newBuffer.set(tokens.indices);
- tokens.indices = newBuffer;
- tokens.indicesLenMinus2 = (newBuffer.length - 2) | 0;
- }
- function add(tokens, start, end) {
- if (tokens.count > tokens.indicesLenMinus2) {
- resize(tokens);
- }
- tokens.indices[tokens.count++] = start;
- tokens.indices[tokens.count++] = end;
- }
- Tokens.add = add;
- function addUnchecked(tokens, start, end) {
- tokens.indices[tokens.count++] = start;
- tokens.indices[tokens.count++] = end;
- }
- Tokens.addUnchecked = addUnchecked;
- function create(size) {
- return {
- indicesLenMinus2: (size - 2) | 0,
- count: 0,
- indices: new Int32Array(size)
- };
- }
- Tokens.create = create;
- })(Tokens || (Tokens = {}));
- /**
- * Represents a column that is not present.
- */
- var _UndefinedColumn = function _UndefinedColumn() {
- this.isDefined = false;
- };
- _UndefinedColumn.prototype.getString = function getString (row) { return null; };
- _UndefinedColumn.prototype.getInteger = function getInteger (row) { return 0; };
- _UndefinedColumn.prototype.getFloat = function getFloat (row) { return 0.0; };
- _UndefinedColumn.prototype.getValuePresence = function getValuePresence (row) { return 1 /* NotSpecified */; };
- _UndefinedColumn.prototype.areValuesEqual = function areValuesEqual (rowA, rowB) { return true; };
- _UndefinedColumn.prototype.stringEquals = function stringEquals (row, value) { return value === null; };
- var UndefinedColumn = new _UndefinedColumn();
- /*
- * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
- *
- * from https://github.com/dsehnal/CIFTools.js
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- var ShortStringPool;
- (function (ShortStringPool) {
- function create() { return Object.create(null); }
- ShortStringPool.create = create;
- function get(pool, str) {
- if (str.length > 6)
- { return str; }
- var value = pool[str];
- if (value !== void 0)
- { return value; }
- pool[str] = str;
- return str;
- }
- ShortStringPool.get = get;
- })(ShortStringPool || (ShortStringPool = {}));
- /**
- * Represents a single column.
- */
- var TextColumn = function TextColumn(table, data, name, index) {
- this.data = data;
- this.name = name;
- this.index = index;
- this.stringPool = ShortStringPool.create();
- this.isDefined = true;
- this.indices = table.indices;
- this.columnCount = table.columnCount;
- };
- /**
- * Returns the string value at given row.
- */
- TextColumn.prototype.getString = function getString (row) {
- var i = (row * this.columnCount + this.index) * 2;
- return ShortStringPool.get(this.stringPool, this.data.substring(this.indices[i], this.indices[i + 1]));
- };
- /**
- * Returns the integer value at given row.
- */
- TextColumn.prototype.getInteger = function getInteger (row) {
- var i = (row * this.columnCount + this.index) * 2;
- return parseInt(this.data, this.indices[i], this.indices[i + 1]);
- };
- /**
- * Returns the float value at given row.
- */
- TextColumn.prototype.getFloat = function getFloat (row) {
- var i = (row * this.columnCount + this.index) * 2;
- return parseFloat(this.data, this.indices[i], this.indices[i + 1]);
- };
- /**
- * Returns true if the token has the specified string value.
- */
- TextColumn.prototype.stringEquals = function stringEquals (row, value) {
- var this$1 = this;
- var aIndex = (row * this.columnCount + this.index) * 2, s = this.indices[aIndex], len = value.length;
- if (len !== this.indices[aIndex + 1] - s)
- { return false; }
- for (var i = 0; i < len; i++) {
- if (this$1.data.charCodeAt(i + s) !== value.charCodeAt(i))
- { return false; }
- }
- return true;
- };
- /**
- * Determines if values at the given rows are equal.
- */
- TextColumn.prototype.areValuesEqual = function areValuesEqual (rowA, rowB) {
- var this$1 = this;
- var aIndex = (rowA * this.columnCount + this.index) * 2;
- var bIndex = (rowB * this.columnCount + this.index) * 2;
- var aS = this.indices[aIndex];
- var bS = this.indices[bIndex];
- var len = this.indices[aIndex + 1] - aS;
- if (len !== this.indices[bIndex + 1] - bS)
- { return false; }
- for (var i = 0; i < len; i++) {
- if (this$1.data.charCodeAt(i + aS) !== this$1.data.charCodeAt(i + bS)) {
- return false;
- }
- }
- return true;
- };
- TextColumn.prototype.getValuePresence = function getValuePresence (row) {
- var index = 2 * (row * this.columnCount + this.index);
- if (this.indices[index] === this.indices[index + 1]) {
- return 1 /* NotSpecified */;
- }
- return 0 /* Present */;
- };
- var CifColumn = (function (TextColumn) {
- function CifColumn () {
- TextColumn.apply(this, arguments);
- }
- if ( TextColumn ) CifColumn.__proto__ = TextColumn;
- CifColumn.prototype = Object.create( TextColumn && TextColumn.prototype );
- CifColumn.prototype.constructor = CifColumn;
- CifColumn.prototype.getString = function getString (row) {
- var ret = TextColumn.prototype.getString.call(this, row);
- if (ret === '.' || ret === '?')
- { return null; }
- return ret;
- };
- /**
- * Returns true if the value is not defined (. or ? token).
- */
- CifColumn.prototype.getValuePresence = function getValuePresence (row) {
- var index = 2 * (row * this.columnCount + this.index);
- var s = this.indices[index];
- if (this.indices[index + 1] - s !== 1)
- { return 0 /* Present */; }
- var v = this.data.charCodeAt(s);
- if (v === 46 /* . */)
- { return 1 /* NotSpecified */; }
- if (v === 63 /* ? */)
- { return 2 /* Unknown */; }
- return 0 /* Present */;
- };
- return CifColumn;
- }(TextColumn));
- /**
- * Represents a table backed by a string.
- */
- var TextTable = function TextTable(data, name, columns, tokens) {
- this.name = name;
- this.indices = tokens.indices;
- this.data = data;
- this.columnCount = columns.length;
- this.rowCount = (tokens.count / 2 / columns.length) | 0;
- this.initColumns(columns);
- };
- var prototypeAccessors = { columnNames: {} };
- prototypeAccessors.columnNames.get = function () {
- return this.columnNameList;
- };
- /**
- * Get a column object that makes accessing data easier.
- */
- TextTable.prototype.getColumn = function getColumn (name) {
- var i = this.columnIndices.get(name);
- if (i !== void 0)
- { return new TextColumn(this, this.data, name, i); }
- return UndefinedColumn;
- };
- TextTable.prototype.initColumns = function initColumns (columns) {
- var this$1 = this;
- this.columnIndices = new Map();
- this.columnNameList = [];
- for (var i = 0; i < columns.length; i++) {
- this$1.columnIndices.set(columns[i], i);
- this$1.columnNameList.push(columns[i]);
- }
- };
- Object.defineProperties( TextTable.prototype, prototypeAccessors );
- var CifTable = (function (TextTable) {
- function CifTable () {
- TextTable.apply(this, arguments);
- }
- if ( TextTable ) CifTable.__proto__ = TextTable;
- CifTable.prototype = Object.create( TextTable && TextTable.prototype );
- CifTable.prototype.constructor = CifTable;
- CifTable.prototype.getColumn = function getColumn (name) {
- var i = this.columnIndices.get(name);
- if (i !== void 0)
- { return new CifColumn(this, this.data, name, i); }
- return UndefinedColumn;
- };
- CifTable.prototype.initColumns = function initColumns (columns) {
- var this$1 = this;
- this.columnIndices = new Map();
- this.columnNameList = [];
- for (var i = 0; i < columns.length; i++) {
- var colName = columns[i].substr(this$1.name.length + 1);
- this$1.columnIndices.set(colName, i);
- this$1.columnNameList.push(colName);
- }
- };
- return CifTable;
- }(TextTable));
- /*
- * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
- *
- * from https://github.com/dsehnal/CIFTools.js
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- var ParserResult;
- (function (ParserResult) {
- function error(message, line) {
- if ( line === void 0 ) line = -1;
- return new ParserError(message, line);
- }
- ParserResult.error = error;
- function success(result, warnings) {
- if ( warnings === void 0 ) warnings = [];
- return new ParserSuccess(result, warnings);
- }
- ParserResult.success = success;
- })(ParserResult || (ParserResult = {}));
- var ParserError = function ParserError(message, line) {
- this.message = message;
- this.line = line;
- this.isError = true;
- };
- ParserError.prototype.toString = function toString () {
- if (this.line >= 0) {
- return ("[Line " + (this.line) + "] " + (this.message));
- }
- return this.message;
- };
- var ParserSuccess = function ParserSuccess(result, warnings) {
- this.result = result;
- this.warnings = warnings;
- this.isError = false;
- };
- /*
- * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
- var GroFile = function GroFile(data) {
- this.blocks = [];
- this.data = data;
- };
- var GroBlock = function GroBlock(data) {
- this.data = data;
- this.tableMap = new Map();
- this.tableList = [];
- };
- GroBlock.prototype.getTable = function getTable (name) {
- return this.tableMap.get(name);
- };
- /**
- * Adds a table.
- */
- GroBlock.prototype.addTable = function addTable (table) {
- this.tableList[this.tableList.length] = table;
- this.tableMap.set(table.name, table);
- };
- function createTokenizer(data) {
- return {
- data: data,
- position: 0,
- length: data.length,
- currentLineNumber: 1,
- currentTokenStart: 0,
- currentTokenEnd: 0,
- numberOfAtoms: 0,
- hasVelocities: false,
- numberOfDecimalPlaces: 3
- };
- }
- /**
- * title string (free format string, optional time in ps after 't=')
- */
- function handleTitleString(state, tokens) {
- eatLine(state);
- // console.log('title', state.data.substring(state.currentTokenStart, state.currentTokenEnd))
- var start = state.currentTokenStart;
- var end = state.currentTokenEnd;
- var valueStart = state.currentTokenStart;
- var valueEnd = start;
- while (valueEnd < end && !isTime(state.data, valueEnd))
- { ++valueEnd; }
- if (isTime(state.data, valueEnd)) {
- var timeStart = valueEnd + 2;
- while (valueEnd > start && isSpaceOrComma(state.data, valueEnd - 1))
- { --valueEnd; }
- Tokens.add(tokens, valueStart, valueEnd); // title
- while (timeStart < end && state.data.charCodeAt(timeStart) === 32)
- { ++timeStart; }
- while (valueEnd > timeStart && state.data.charCodeAt(valueEnd - 1) === 32)
- { --valueEnd; }
- Tokens.add(tokens, timeStart, end); // time
- }
- else {
- Tokens.add(tokens, valueStart, valueEnd); // title
- Tokens.add(tokens, valueEnd, valueEnd); // empty token for time
- }
- }
- function isSpaceOrComma(data, position) {
- var c = data.charCodeAt(position);
- return c === 32 || c === 44;
- }
- function isTime(data, position) {
- // T/t
- var c = data.charCodeAt(position);
- if (c !== 84 && c !== 116)
- { return false; }
- // =
- if (data.charCodeAt(position + 1) !== 61)
- { return false; }
- return true;
- }
- // function isDot(state: TokenizerState): boolean {
- // // .
- // if (state.data.charCodeAt(state.currentTokenStart) !== 46) return false;
- // return true;
- // }
- // function numberOfDecimalPlaces (state: TokenizerState) {
- // // var ndec = firstLines[ 2 ].length - firstLines[ 2 ].lastIndexOf('.') - 1
- // const start = state.currentTokenStart
- // const end = state.currentTokenEnd
- // for (let i = end; start < i; --i) {
- // // .
- // if (state.data.charCodeAt(i) === 46) return end - start - i
- // }
- // throw new Error('Could not determine number of decimal places')
- // }
- /**
- * number of atoms (free format integer)
- */
- function handleNumberOfAtoms(state, tokens) {
- skipWhitespace(state);
- state.currentTokenStart = state.position;
- eatValue(state);
- state.numberOfAtoms = parseInt(state.data, state.currentTokenStart, state.currentTokenEnd);
- Tokens.add(tokens, state.currentTokenStart, state.currentTokenEnd);
- eatLine(state);
- }
- // function checkForVelocities (state: GroState) {
- // }
- /**
- * This format is fixed, ie. all columns are in a fixed position.
- * Optionally (for now only yet with trjconv) you can write gro files
- * with any number of decimal places, the format will then be n+5
- * positions with n decimal places (n+1 for velocities) in stead
- * of 8 with 3 (with 4 for velocities). Upon reading, the precision
- * will be inferred from the distance between the decimal points
- * (which will be n+5). Columns contain the following information
- * (from left to right):
- * residue number (5 positions, integer)
- * residue name (5 characters)
- * atom name (5 characters)
- * atom number (5 positions, integer)
- * position (in nm, x y z in 3 columns, each 8 positions with 3 decimal places)
- * velocity (in nm/ps (or km/s), x y z in 3 columns, each 8 positions with 4 decimal places)
- */
- function handleAtoms(state, block) {
- var name = 'atoms';
- var columns = ['residueNumber', 'residueName', 'atomName', 'atomNumber', 'x', 'y', 'z'];
- if (state.hasVelocities) {
- columns.push('vx', 'vy', 'vz');
- }
- var fieldSizes = [5, 5, 5, 5, 8, 8, 8, 8, 8, 8];
- var columnCount = columns.length;
- var tokens = Tokens.create(state.numberOfAtoms * 2 * columnCount);
- var start;
- var end;
- var valueStart;
- var valueEnd = state.position;
- for (var i = 0; i < state.numberOfAtoms; ++i) {
- state.currentTokenStart = state.position;
- end = state.currentTokenStart;
- for (var j = 0; j < columnCount; ++j) {
- start = end;
- end = start + fieldSizes[j];
- // trim
- valueStart = start;
- valueEnd = end;
- while (valueStart < valueEnd && state.data.charCodeAt(valueStart) === 32)
- { ++valueStart; }
- while (valueEnd > valueStart && state.data.charCodeAt(valueEnd - 1) === 32)
- { --valueEnd; }
- Tokens.addUnchecked(tokens, valueStart, valueEnd);
- }
- state.position = valueEnd;
- eatLine(state);
- }
- block.addTable(new TextTable(state.data, name, columns, tokens));
- }
- /**
- * box vectors (free format, space separated reals), values:
- * v1(x) v2(y) v3(z) v1(y) v1(z) v2(x) v2(z) v3(x) v3(y),
- * the last 6 values may be omitted (they will be set to zero).
- * Gromacs only supports boxes with v1(y)=v1(z)=v2(z)=0.
- */
- function handleBoxVectors(state, tokens) {
- // just read the first three values, ignore any remaining
- for (var i = 0; i < 3; ++i) {
- skipWhitespace(state);
- state.currentTokenStart = state.position;
- eatValue(state);
- Tokens.add(tokens, state.currentTokenStart, state.currentTokenEnd);
- }
- }
- /**
- * Creates an error result.
- */
- // function error(line: number, message: string) {
- // return ParserResult.error<GroFile>(message, line);
- // }
- /**
- * Creates a data result.
- */
- function result(data) {
- return ParserResult.success(data);
- }
- function parseInternal(data) {
- var state = createTokenizer(data);
- var file = new GroFile(data);
- var block = new GroBlock(data);
- file.blocks.push(block);
- var headerColumns = ['title', 'timeInPs', 'numberOfAtoms', 'boxX', 'boxY', 'boxZ'];
- var headerTokens = Tokens.create(2 * headerColumns.length);
- var header = new TextTable(state.data, 'header', headerColumns, headerTokens);
- block.addTable(header);
- handleTitleString(state, headerTokens);
- handleNumberOfAtoms(state, headerTokens);
- handleAtoms(state, block);
- handleBoxVectors(state, headerTokens);
- return result(file);
- }
- function parse(data) {
- return parseInternal(data);
- }
- export { parse as groReader };
- //# sourceMappingURL=molio.esm.js.map
|