diff --git a/src/reader/cif/data-model.ts b/src/reader/cif/data-model.ts index 43282aad4e6e711a9084d861a08fef712b9efac9..642cf5621198cf811ba1997847cd3f7b2cb1cd6a 100644 --- a/src/reader/cif/data-model.ts +++ b/src/reader/cif/data-model.ts @@ -60,9 +60,27 @@ export interface Field { presence(row: number): ValuePresence, areValuesEqual(rowA: number, rowB: number): boolean, - stringEquals(row: number, value: string | null): boolean, + stringEquals(row: number, value: string): boolean, - toStringArray(ctor?: (size: number) => Column.ArrayType, startRow?: number, endRowExclusive?: number): ReadonlyArray<string>, - toIntArray(ctor?: (size: number) => Column.ArrayType, startRow?: number, endRowExclusive?: number): ReadonlyArray<number>, - toFloatArray(ctor?: (size: number) => Column.ArrayType, startRow?: number, endRowExclusive?: number): ReadonlyArray<number> + toStringArray(params?: Column.ToArrayParams): ReadonlyArray<string>, + toIntArray(params?: Column.ToArrayParams): ReadonlyArray<number>, + toFloatArray(params?: Column.ToArrayParams): ReadonlyArray<number> +} + +export function DefaultUndefinedField(rowCount: number): Field { + return { + isDefined: false, + rowCount, + str: row => '', + int: row => 0, + float: row => 0, + + presence: row => ValuePresence.NotSpecified, + areValuesEqual: (rowA, rowB) => true, + stringEquals: (row, value) => value === null, + + toStringArray: (p) => Column.createArray(rowCount, p).array, + toIntArray: (p) => Column.createArray(rowCount, p).array, + toFloatArray: (p) => Column.createArray(rowCount, p).array + }; } \ No newline at end of file diff --git a/src/reader/cif/schema.ts b/src/reader/cif/schema.ts index 2826c9b88bb655d5ea0f86b785f8b405cb068c34..1244827e106807e112480733475a8ac889cce6ab 100644 --- a/src/reader/cif/schema.ts +++ b/src/reader/cif/schema.ts @@ -48,55 +48,45 @@ export type Category<Fields> = Fields & { export namespace Category { export type Schema = { '@alias'?: string } & { [field: string]: Field.Schema<any> } - export type Instance<T extends Schema> = Category<{ [F in keyof T]: Field<T[F]['type']> }> + export type Instance<T extends Schema> = Category<{ [F in keyof T]: Column.Column<T[F]['type']> }> } -export interface Field<T> { - readonly isDefined: boolean, - value(row: number): T, - presence(row: number): Data.ValuePresence, - areValuesEqual(rowA: number, rowB: number): boolean, - stringEquals(row: number, value: string | null): boolean, - /** Converts the selected row range to an array. ctor might or might not be called depedning on the source data format. */ - toArray(ctor?: (size: number) => Column.ArrayType, startRow?: number, endRowExclusive?: number): ReadonlyArray<T> | undefined -} +// export interface Field<T> { +// readonly isDefined: boolean, +// value(row: number): T, +// presence(row: number): Data.ValuePresence, +// areValuesEqual(rowA: number, rowB: number): boolean, +// stringEquals(row: number, value: string | null): boolean, +// /** Converts the selected row range to an array. ctor might or might not be called depedning on the source data format. */ +// toArray(params?: Column.ToArrayParams): ReadonlyArray<T> +// } export namespace Field { - export interface Schema<T> { type: T, ctor: (field: Data.Field) => Field<T>, undefinedField: (c: number) => Data.Field, alias?: string }; + export interface Schema<T> { type: T, ctor: (field: Data.Field) => Column.Column<T>, undefinedField: (c: number) => Data.Field, alias?: string }; export interface Spec { undefinedField?: (c: number) => Data.Field, alias?: string } export function str(spec?: Spec) { return createSchema(spec, Str); } export function int(spec?: Spec) { return createSchema(spec, Int); } export function float(spec?: Spec) { return createSchema(spec, Float); } - function create<T>(field: Data.Field, value: (row: number) => T, toArray: Field<T>['toArray']): Field<T> { - return { isDefined: field.isDefined, value, presence: field.presence, areValuesEqual: field.areValuesEqual, stringEquals: field.stringEquals, toArray }; + function create<T>(field: Data.Field, value: (row: number) => T, toArray: Column.Column<T>['toArray']): Column.Column<T> { + const presence = field.presence; + return { + isDefined: field.isDefined, + rowCount: field.rowCount, + value, + isValueDefined: row => presence(row) === Data.ValuePresence.Present, + areValuesEqual: field.areValuesEqual, + toArray + }; } function Str(field: Data.Field) { return create(field, field.str, field.toStringArray); } function Int(field: Data.Field) { return create(field, field.int, field.toIntArray); } function Float(field: Data.Field) { return create(field, field.float, field.toFloatArray); } - function defaultUndefined(rowCount: number): Data.Field { - return { - isDefined: false, - rowCount, - str: row => '', - int: row => 0, - float: row => 0, - - presence: row => Data.ValuePresence.NotSpecified, - areValuesEqual: (rowA, rowB) => true, - stringEquals: (row, value) => value === null, - - toStringArray: (ctor, s, e) => Column.createArray(rowCount, ctor, s, e).array, - toIntArray: (ctor, s, e) => Column.createArray(rowCount, ctor, s, e).array, - toFloatArray: (ctor, s, e) => Column.createArray(rowCount, ctor, s, e).array - }; - } - - function createSchema<T>(spec: Spec | undefined, ctor: (field: Data.Field) => Field<T>): Schema<T> { - return { type: 0 as any, ctor, undefinedField: (spec && spec.undefinedField) || defaultUndefined, alias: spec && spec.alias }; + function createSchema<T>(spec: Spec | undefined, ctor: (field: Data.Field) => Column.Column<T>): Schema<T> { + return { type: 0 as any, ctor, undefinedField: (spec && spec.undefinedField) || Data.DefaultUndefinedField, alias: spec && spec.alias }; } } diff --git a/src/reader/cif/text-field.ts b/src/reader/cif/text-field.ts index c3d4d96b4b4d8047096c1eb726359f05a60ebdee..f09893691d31d15a013bedd6a68a711191bce093 100644 --- a/src/reader/cif/text-field.ts +++ b/src/reader/cif/text-field.ts @@ -42,7 +42,7 @@ export default function CifTextField(data: string, tokens: ArrayLike<number>, ro int, float, presence, - areValuesEqual: (rowA, rowB) => { + areValuesEqual(rowA, rowB) { const aS = tokens[2 * rowA], bS = tokens[2 * rowB]; const len = tokens[2 * rowA + 1] - aS; if (len !== tokens[2 * rowB + 1] - bS) return false; @@ -53,7 +53,7 @@ export default function CifTextField(data: string, tokens: ArrayLike<number>, ro } return true; }, - stringEquals: (row, value) => { + stringEquals(row, value) { const s = tokens[2 * row]; if (!value) return presence(row) !== Data.ValuePresence.Present; const len = value.length; @@ -63,16 +63,16 @@ export default function CifTextField(data: string, tokens: ArrayLike<number>, ro } return true; }, - toStringArray: (ctor, s, e) => { - const { array, start } = Column.createArray(rowCount, ctor, s, e); + toStringArray(params) { + const { array, start } = Column.createArray(rowCount, params); return fillArrayValues(str, array, start); }, - toIntArray: (ctor, s, e) => { - const { array, start } = Column.createArray(rowCount, ctor, s, e); + toIntArray(params) { + const { array, start } = Column.createArray(rowCount, params); return fillArrayValues(int, array, start); }, - toFloatArray: (ctor, s, e) => { - const { array, start } = Column.createArray(rowCount, ctor, s, e); + toFloatArray(params) { + const { array, start } = Column.createArray(rowCount, params); return fillArrayValues(float, array, start); } } diff --git a/src/reader/common/column.ts b/src/reader/common/column.ts index cce941251a75b09b1902188a28ac511d7415537e..dab5ac0636d151bd8667a0b430eb9f85b06de521 100644 --- a/src/reader/common/column.ts +++ b/src/reader/common/column.ts @@ -4,7 +4,6 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -export type ArrayType = string[] | number[] | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array export type ColumnType = typeof ColumnType.str | typeof ColumnType.pooledStr | typeof ColumnType.int | typeof ColumnType.float export namespace ColumnType { @@ -14,11 +13,21 @@ export namespace ColumnType { export const float = { '@type': 0 as number, kind: 'float' as 'float' }; } +export interface ToArrayParams { + array?: { new(size: number): ArrayLike<number> }, + /** First row */ + start?: number, + /** Last row (exclusive) */ + end?: number +} + export interface Column<T> { readonly isDefined: boolean, readonly rowCount: number, value(row: number): T, - toArray(ctor?: (size: number) => ArrayType, startRow?: number, endRowExclusive?: number): ReadonlyArray<T> + isValueDefined(row: number): boolean, + toArray(params?: ToArrayParams): ReadonlyArray<T>, + areValuesEqual(rowA: number, rowB: number): boolean } export function UndefinedColumn<T extends ColumnType>(rowCount: number, type: T): Column<T['@type']> { @@ -27,18 +36,21 @@ export function UndefinedColumn<T extends ColumnType>(rowCount: number, type: T) isDefined: false, rowCount, value, - toArray(ctor, s, e) { - const { array } = createArray(rowCount, ctor, s, e); + isValueDefined(row) { return false; }, + toArray(params) { + const { array } = createArray(rowCount, params); for (let i = 0, _i = array.length; i < _i; i++) array[i] = value(0) return array; - } + }, + areValuesEqual() { return true; } } } /** A helped function for Column.toArray */ -export function createArray(rowCount: number, ctor?: (size: number) => ArrayType, start?: number, end?: number) { - const c = typeof ctor !== 'undefined' ? ctor : (s: number) => new Array(s); +export function createArray(rowCount: number, params?: ToArrayParams) { + const { array, start, end } = params || ({} as ToArrayParams); + const c = typeof array !== 'undefined' ? array : Array; const s = typeof start !== 'undefined' ? Math.max(Math.min(start, rowCount - 1), 0) : 0; const e = typeof end !== 'undefined' ? Math.min(end, rowCount) : rowCount; - return { array: c(e - s) as any[], start: s, end: e }; + return { array: new c(e - s) as any[], start: s, end: e }; } \ No newline at end of file diff --git a/src/reader/common/text/column/fixed.ts b/src/reader/common/text/column/fixed.ts index 768093d824e4263d758cec026cd94d9dca3e2511..bb307f96948dd2f14049aff68282b83a8b1a9858 100644 --- a/src/reader/common/text/column/fixed.ts +++ b/src/reader/common/text/column/fixed.ts @@ -5,19 +5,13 @@ */ import { Column, ColumnType, createArray } from '../../column' -import { trimStr } from '../tokenizer' +import { trimStr, Lines } from '../tokenizer' import { parseIntSkipLeadingWhitespace, parseFloatSkipLeadingWhitespace } from '../number-parser' import StringPool from '../../../../utils/short-string-pool' -export interface FixedColumnInfo { - data: string, - lines: ArrayLike<number>, - rowCount: number -} - -export default function FixedColumnProvider(info: FixedColumnInfo) { +export default function FixedColumnProvider(lines: Lines) { return function<T extends ColumnType>(offset: number, width: number, type: T) { - return FixedColumn(info, offset, width, type); + return FixedColumn(lines, offset, width, type); } } @@ -26,39 +20,43 @@ function fillArrayValues(value: (row: number) => any, target: any[], start: numb return target; } -export function FixedColumn<T extends ColumnType>(info: FixedColumnInfo, offset: number, width: number, type: T): Column<T['@type']> { - const { data, lines, rowCount } = info; +export function FixedColumn<T extends ColumnType>(lines: Lines, offset: number, width: number, type: T): Column<T['@type']> { + const { data, tokens, count: rowCount } = lines; const { kind } = type; const pool = kind === 'pooled-str' ? StringPool.create() : void 0; const value: Column<T['@type']>['value'] = kind === 'str' ? row => { - let s = lines[2 * row] + offset, le = lines[2 * row + 1]; + let s = tokens[2 * row] + offset, le = tokens[2 * row + 1]; if (s >= le) return ''; let e = s + width; if (e > le) e = le; return trimStr(data, s, e); } : kind === 'pooled-str' ? row => { - let s = lines[2 * row] + offset, le = lines[2 * row + 1]; + let s = tokens[2 * row] + offset, le = tokens[2 * row + 1]; if (s >= le) return ''; let e = s + width; if (e > le) e = le; return StringPool.get(pool!, trimStr(data, s, e)); } : kind === 'int' ? row => { - const s = lines[2 * row] + offset; - if (s > lines[2 * row + 1]) return 0; + const s = tokens[2 * row] + offset; + if (s > tokens[2 * row + 1]) return 0; return parseIntSkipLeadingWhitespace(data, s, s + width); } : row => { - const s = lines[2 * row] + offset; - if (s > lines[2 * row + 1]) return 0; + const s = tokens[2 * row] + offset; + if (s > tokens[2 * row + 1]) return 0; return parseFloatSkipLeadingWhitespace(data, s, s + width); }; return { isDefined: true, rowCount, value, - toArray(ctor, s, e) { - const { array, start } = createArray(rowCount, ctor, s, e); + isValueDefined(row) { return true; }, + toArray(params) { + const { array, start } = createArray(rowCount, params); return fillArrayValues(value, array, start); + }, + areValuesEqual(rowA, rowB) { + return value(rowA) === value(rowB); } }; } \ No newline at end of file diff --git a/src/reader/common/text/tokenizer.ts b/src/reader/common/text/tokenizer.ts index b957a35b1c2f22a4054845ebd27eb57429c29a9b..97fb00ef7f6268b838da77ac0ab9edeb2f6b8f73 100644 --- a/src/reader/common/text/tokenizer.ts +++ b/src/reader/common/text/tokenizer.ts @@ -6,7 +6,7 @@ * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -export interface State<TokenType = any> { +export interface Tokenizer { data: string position: number @@ -15,132 +15,150 @@ export interface State<TokenType = any> { currentLineNumber: number currentTokenStart: number currentTokenEnd: number +} - currentTokenType: TokenType +export interface Lines { + data: string, + count: number, + tokens: ArrayLike<number> } -export function State<TokenType>(data: string, initialTokenType?: TokenType): State<TokenType> { +export function Tokenizer(data: string): Tokenizer { return { data, position: 0, length: data.length, currentLineNumber: 1, currentTokenStart: 0, - currentTokenEnd: 0, - currentTokenType: initialTokenType! + currentTokenEnd: 0 }; } -export function getTokenString(state: State) { - return state.data.substring(state.currentTokenStart, state.currentTokenEnd); -} +export namespace Tokenizer { -/** - * Eat everything until a newline occurs. - */ -export function eatLine(state: State) { - const { data } = state; - while (state.position < state.length) { - switch (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 (data.charCodeAt(state.position) === 10) { + export function getTokenString(state: Tokenizer) { + return state.data.substring(state.currentTokenStart, state.currentTokenEnd); + } + + /** + * Eat everything until a newline occurs. + */ + export function eatLine(state: Tokenizer) { + const { data } = state; + while (state.position < state.length) { + switch (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 (data.charCodeAt(state.position) === 10) { + ++state.position; + } + return; + default: ++state.position; - } - return; - default: - ++state.position; - break; + break; + } } + state.currentTokenEnd = state.position; } - state.currentTokenEnd = state.position; -} -/** Sets the current token start to the current position */ -export function markStart(state: State) { - state.currentTokenStart = state.position; -} + /** Sets the current token start to the current position */ + export function markStart(state: Tokenizer) { + state.currentTokenStart = state.position; + } -/** Sets the current token start to current position and moves to the next line. */ -export function markLine(state: State) { - state.currentTokenStart = state.position; - eatLine(state); -} + /** Sets the current token start to current position and moves to the next line. */ + export function markLine(state: Tokenizer) { + state.currentTokenStart = state.position; + eatLine(state); + } -/** - * Eat everything until a whitespace/newline occurs. - */ -export function eatValue(state: 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; + /** Advance the state by the given number of lines and return line starts/ends as tokens. */ + export function readLines(state: Tokenizer, count: number): Lines { + const lineTokens = Tokens.create(count * 2); + + for (let i = 0; i < count; i++) { + markLine(state); + Tokens.addUnchecked(lineTokens, state.currentTokenStart, state.currentTokenEnd); + } + + return { data: state.data, count, tokens: lineTokens.indices }; + } + + /** + * Eat everything until a whitespace/newline occurs. + */ + export function eatValue(state: Tokenizer) { + 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; } - state.currentTokenEnd = state.position; -} -/** - * Skips all the whitespace - space, tab, newline, CR - * Handles incrementing line count. - */ -export function skipWhitespace(state: State): number { - let prev = 10; - while (state.position < state.length) { - let 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) { + /** + * Skips all the whitespace - space, tab, newline, CR + * Handles incrementing line count. + */ + export function skipWhitespace(state: Tokenizer): number { + let prev = 10; + while (state.position < state.length) { + let 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; - } - prev = c; - ++state.position; - break; - case 13: // \r - prev = c; - ++state.position; - ++state.currentLineNumber; - break; - default: - return prev; + break; + default: + return prev; + } } + return prev; } - return prev; -} -/** Trims spaces and tabs */ -export function trim(state: State, start: number, end: number) { - const { data } = state; - let s = start, e = end - 1; + /** Trims spaces and tabs */ + export function trim(state: Tokenizer, start: number, end: number) { + const { data } = state; + let s = start, e = end - 1; - let c = data.charCodeAt(s); - while ((c === 9 || c === 32) && s <= e) c = data.charCodeAt(++s); - c = data.charCodeAt(e); - while ((c === 9 || c === 32) && e >= s) c = data.charCodeAt(--e); + let c = data.charCodeAt(s); + while ((c === 9 || c === 32) && s <= e) c = data.charCodeAt(++s); + c = data.charCodeAt(e); + while ((c === 9 || c === 32) && e >= s) c = data.charCodeAt(--e); - state.currentTokenStart = s; - state.currentTokenEnd = e + 1; - state.position = end; + state.currentTokenStart = s; + state.currentTokenEnd = e + 1; + state.position = end; + } } export function trimStr(data: string, start: number, end: number) { @@ -189,8 +207,4 @@ export namespace Tokens { } } - -/** - * A helper for building a typed array of token indices. - */ -export default Tokens \ No newline at end of file +export default Tokenizer \ No newline at end of file diff --git a/src/reader/gro/parser.ts b/src/reader/gro/parser.ts index 3ab681ffa03b10c1723fe2b2a53355d119b01d31..bca4df98a20d8fa6c79c112f238d57f7250568fb 100644 --- a/src/reader/gro/parser.ts +++ b/src/reader/gro/parser.ts @@ -5,14 +5,14 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { State as TokenizerState, Tokens, markLine, getTokenString } from '../common/text/tokenizer' +import Tokenizer from '../common/text/tokenizer' import FixedColumn from '../common/text/column/fixed' import { ColumnType, UndefinedColumn } from '../common/column' import * as Schema from './schema' import Result from '../result' interface State { - tokenizer: TokenizerState, + tokenizer: Tokenizer, header: Schema.Header, numberOfAtoms: number, } @@ -27,7 +27,7 @@ function createEmptyHeader(): Schema.Header { }; } -function createState(tokenizer: TokenizerState): State { +function State(tokenizer: Tokenizer): State { return { tokenizer, header: createEmptyHeader(), @@ -40,14 +40,14 @@ function createState(tokenizer: TokenizerState): State { */ function handleTitleString(state: State) { const { tokenizer, header } = state; - markLine(tokenizer); + Tokenizer.markLine(tokenizer); - let line = getTokenString(tokenizer); + let line = Tokenizer.getTokenString(tokenizer); // skip potential empty lines... if (line.trim().length === 0) { - markLine(tokenizer); - line = getTokenString(tokenizer); + Tokenizer.markLine(tokenizer); + line = Tokenizer.getTokenString(tokenizer); } const timeOffset = line.lastIndexOf('t='); @@ -67,8 +67,8 @@ function handleTitleString(state: State) { */ function handleNumberOfAtoms(state: State) { const { tokenizer } = state; - markLine(tokenizer); - const line = getTokenString(tokenizer); + Tokenizer.markLine(tokenizer); + const line = Tokenizer.getTokenString(tokenizer); state.numberOfAtoms = parseInt(line); } @@ -90,17 +90,12 @@ function handleNumberOfAtoms(state: State) { */ function handleAtoms(state: State): Schema.Atoms { const { tokenizer, numberOfAtoms } = state; - const lineTokens = Tokens.create(numberOfAtoms * 2); + const lines = Tokenizer.readLines(tokenizer, numberOfAtoms); - for (let i = 0; i < numberOfAtoms; i++) { - markLine(tokenizer); - Tokens.addUnchecked(lineTokens, tokenizer.currentTokenStart, tokenizer.currentTokenEnd); - } - - const lines = lineTokens.indices; - const positionSample = tokenizer.data.substring(lines[0], lines[1]).substring(20); + const positionSample = tokenizer.data.substring(lines.tokens[0], lines.tokens[1]).substring(20); const precisions = positionSample.match(/\.\d+/g)!; const hasVelocities = precisions.length === 6; + state.header.hasVelocities = hasVelocities; state.header.precision.position = precisions[0].length - 1; state.header.precision.velocity = hasVelocities ? precisions[3].length - 1 : 0; @@ -110,7 +105,7 @@ function handleAtoms(state: State): Schema.Atoms { const vO = pO + 3 * pW; const vW = state.header.precision.velocity + 4; - const col = FixedColumn({ data: tokenizer.data, lines, rowCount: state.numberOfAtoms }); + const col = FixedColumn(lines); const undef = UndefinedColumn(state.numberOfAtoms, ColumnType.float); const ret = { @@ -138,17 +133,17 @@ function handleAtoms(state: State): Schema.Atoms { */ function handleBoxVectors(state: State) { const { tokenizer } = state; - markLine(tokenizer); - const values = getTokenString(tokenizer).trim().split(/\s+/g); + Tokenizer.markLine(tokenizer); + const values = Tokenizer.getTokenString(tokenizer).trim().split(/\s+/g); state.header.box = [+values[0], +values[1], +values[2]]; } function parseInternal(data: string): Result<Schema.File> { - const tokenizer = TokenizerState(data); + const tokenizer = Tokenizer(data); const structures: Schema.Structure[] = []; while (tokenizer.position < data.length) { - const state = createState(tokenizer); + const state = State(tokenizer); handleTitleString(state); handleNumberOfAtoms(state); const atoms = handleAtoms(state); diff --git a/src/reader/spec/cif.spec.ts b/src/reader/spec/cif.spec.ts index bf1ed46f7cf73d8f35c449bbe2aa7a5cba6b8bad..80b4c1388e0dfbf5c068f2a76ac6aad9abb516dd 100644 --- a/src/reader/spec/cif.spec.ts +++ b/src/reader/spec/cif.spec.ts @@ -34,7 +34,7 @@ describe('schema', () => { }); it('toArray', () => { - const ret = data.atoms.x.toArray(s => new Int32Array(s))!; + const ret = data.atoms.x.toArray({ array: Int32Array }); expect(ret.length).toBe(3); expect(ret[0]).toBe(1); expect(ret[1]).toBe(2); diff --git a/src/reader/spec/fixed-column.spec.ts b/src/reader/spec/fixed-column.spec.ts index 98ff6067d9668f791593e7c7646531ec28ce58bb..c91bfb7424123b420f8235d34173b9987667b433 100644 --- a/src/reader/spec/fixed-column.spec.ts +++ b/src/reader/spec/fixed-column.spec.ts @@ -30,7 +30,7 @@ const linesTokens = (function () { }()); describe('fixed text column', () => { - const col = FixedColumn({ data, lines: linesTokens, rowCount: lines.length }); + const col = FixedColumn({ data, tokens: linesTokens, count: lines.length }); const col1 = col(0, 5, ColumnType.float); const col2 = col(5, 4, ColumnType.str); it('number', () => { diff --git a/src/script.ts b/src/script.ts index 3ce16a830394b2c4e673f0b50b9d677b66d7c35b..ea36fe76a625e31c2440447c1d3eca2dc8db0ed1 100644 --- a/src/script.ts +++ b/src/script.ts @@ -51,22 +51,22 @@ export function _gro() { console.log('rowCount', n) console.time('getFloatArray x') - const x = atoms.x.toArray(x => new Float32Array(x))! + const x = atoms.x.toArray({ array: Float32Array }) console.timeEnd('getFloatArray x') console.log(x.length, x[0], x[x.length - 1]) console.time('getFloatArray y') - const y = atoms.y.toArray(x => new Float32Array(x))! + const y = atoms.y.toArray({ array: Float32Array }) console.timeEnd('getFloatArray y') console.log(y.length, y[0], y[y.length - 1]) console.time('getFloatArray z') - const z = atoms.z.toArray(x => new Float32Array(x))! + const z = atoms.z.toArray({ array: Float32Array }) console.timeEnd('getFloatArray z') console.log(z.length, z[0], z[z.length - 1]) console.time('getIntArray residueNumber') - const residueNumber = atoms.residueNumber.toArray(x => new Int32Array(x))! + const residueNumber = atoms.residueNumber.toArray({ array: Int32Array }) console.timeEnd('getIntArray residueNumber') console.log(residueNumber.length, residueNumber[0], residueNumber[residueNumber.length - 1]) });