diff --git a/src/apps/domain-annotation-server/utils.ts b/src/apps/domain-annotation-server/utils.ts index 7c3e91b2a8866a051379e8b35cafdbe7d4de0022..df4a64171545c2b8746a603e8a47ba6cd449a2f2 100644 --- a/src/apps/domain-annotation-server/utils.ts +++ b/src/apps/domain-annotation-server/utils.ts @@ -20,7 +20,7 @@ function ofSchema(schema: Table.Schema) { const fields: Encoder.FieldDefinition[] = []; for (const k of Object.keys(schema)) { const t = schema[k]; - const type: any = t.kind === 'str' ? Encoder.FieldType.Str : t.kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float; + const type: any = t.valueKind === 'str' ? Encoder.FieldType.Str : t.valueKind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float; fields.push({ name: k, type, value: columnValue(k), valueKind: columnValueKind(k) }) } return fields; diff --git a/src/mol-data/db/_spec/table.spec.ts b/src/mol-data/db/_spec/table.spec.ts index 9f61d1bafd57d7b8702b82da93f098cc17a13df9..51965938a4597c63847e02ee1a0d14a814d55e31 100644 --- a/src/mol-data/db/_spec/table.spec.ts +++ b/src/mol-data/db/_spec/table.spec.ts @@ -9,14 +9,14 @@ import Column from '../column' import Table from '../table' describe('column', () => { - const cc = Column.ofConst(10, 2, Column.Type.int); - const arr = Column.ofArray({ array: [1, 2, 3, 4], type: Column.Type.int }); + const cc = Column.ofConst(10, 2, Column.Schema.int); + const arr = Column.ofArray({ array: [1, 2, 3, 4], schema: Column.Schema.int }); const arrWindow = Column.window(arr, 1, 3); - const typed = Column.ofArray({ array: new Int32Array([1, 2, 3, 4]), type: Column.Type.int }); + const typed = Column.ofArray({ array: new Int32Array([1, 2, 3, 4]), schema: Column.Schema.int }); const typedWindow = Column.window(typed, 1, 3); - const numStr = Column.ofArray({ array: [1, 2] as any, type: Column.Type.str }); + const numStr = Column.ofArray({ array: [1, 2] as any, schema: Column.Schema.str }); it('constant', () => { expect(cc.rowCount).toBe(2); @@ -68,8 +68,8 @@ describe('table', () => { it('ofColumns', () => { const t = Table.ofColumns(schema, { - x: Column.ofArray({ array: [10, -1], type: Column.Type.int }), - n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }), + x: Column.ofArray({ array: [10, -1], schema: Column.Schema.int }), + n: Column.ofArray({ array: ['row1', 'row2'], schema: Column.Schema.str }), }); expect(t.x.toArray()).toEqual([10, -1]); expect(t.n.toArray()).toEqual(['row1', 'row2']); @@ -86,11 +86,11 @@ describe('table', () => { it('pickColumns', () => { const t = Table.ofColumns(schema, { - x: Column.ofArray({ array: [10, -1], type: Column.Type.int }), - n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }), + x: Column.ofArray({ array: [10, -1], schema: Column.Schema.int }), + n: Column.ofArray({ array: ['row1', 'row2'], schema: Column.Schema.str }), }); const s = { x: Column.Schema.int, y: Column.Schema.int }; - const picked = Table.pickColumns(s, t, { y: Column.ofArray({ array: [3, 4], type: Column.Type.int })}); + const picked = Table.pickColumns(s, t, { y: Column.ofArray({ array: [3, 4], schema: Column.Schema.int })}); expect(picked._columns).toEqual(['x', 'y']); expect(picked._rowCount).toEqual(2); expect(picked.x.toArray()).toEqual([10, -1]); @@ -99,8 +99,8 @@ describe('table', () => { it('view', () => { const t = Table.ofColumns(schema, { - x: Column.ofArray({ array: [10, -1], type: Column.Type.int }), - n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }), + x: Column.ofArray({ array: [10, -1], schema: Column.Schema.int }), + n: Column.ofArray({ array: ['row1', 'row2'], schema: Column.Schema.str }), }); const s = { x: Column.Schema.int }; const view = Table.view(t, s, [1]); @@ -111,8 +111,8 @@ describe('table', () => { it('sort', () => { const t = Table.ofColumns<typeof schema>(schema, { - x: Column.ofArray({ array: [10, -1], type: Column.Type.int }), - n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }), + x: Column.ofArray({ array: [10, -1], schema: Column.Schema.int }), + n: Column.ofArray({ array: ['row1', 'row2'], schema: Column.Schema.str }), }); const { x } = t; const sorted = Table.sort(t, (i, j) => x.value(i) - x.value(j)) diff --git a/src/mol-data/db/column.ts b/src/mol-data/db/column.ts index 484411e6f5a5ed91acefbd55739727157b9f20e6..6d5701217e1c20442abfa3249ba6a2ccde9fef49 100644 --- a/src/mol-data/db/column.ts +++ b/src/mol-data/db/column.ts @@ -8,7 +8,7 @@ import * as ColumnHelpers from './column-helpers' import { Tensor as Tensors } from 'mol-math/linear-algebra' interface Column<T> { - readonly '@type': Column.Type, + readonly _schema: Column.Schema, readonly '@array': ArrayLike<any> | undefined, readonly isDefined: boolean, @@ -20,53 +20,30 @@ interface Column<T> { } namespace Column { - export type Type<T = any> = Type.Str | Type.Int | Type.Float | Type.Tensor | Type.Aliased<T> export type ArrayCtor<T> = { new(size: number): ArrayLike<T> } - export namespace Type { - export type Str = { T: string, kind: 'str' } - export type Int = { T: number, kind: 'int' } - export type Float = { T: number, kind: 'float' } - export type Tensor = { T: Tensors, space: Tensors.Space, kind: 'tensor' }; - export type Aliased<T> = { T: T } & { kind: 'str' | 'int' | 'float' } - - export const str: Str = { T: '', kind: 'str' }; - export const int: Int = { T: 0, kind: 'int' }; - export const float: Float = { T: 0, kind: 'float' }; - - export function tensor(space: Tensors.Space): Tensor { return { T: space.create(), space, kind: 'tensor' }; } - export function aliased<T>(t: Type): Aliased<T> { return t as any as Aliased<T>; } - } - export type Schema<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> | Schema.Tensor export namespace Schema { - export interface FloatPrecision { - low: number, - acceptable: number, - full: number - } - export type Scalar<T = any> = Schema.Str | Schema.Int | Schema.Float | Schema.Coordinate | Schema.Aliased<T> - export function FP(full: number, acceptable: number, low: number): FloatPrecision { return { low, full, acceptable }; } - - export type Str = { '@type': 'str', T: string, kind: 'str' } - export type Int = { '@type': 'int', T: number, kind: 'int' } - export type Float = { '@type': 'float', T: number, kind: 'float', precision: FloatPrecision } - export type Coordinate = { '@type': 'coord', T: number, kind: 'float' } + export type Str = { '@type': 'str', T: string, valueKind: 'str' } + export type Int = { '@type': 'int', T: number, valueKind: 'int' } + export type Float = { '@type': 'float', T: number, valueKind: 'float' } + export type Coordinate = { '@type': 'coord', T: number, valueKind: 'float' } - export type Tensor = { '@type': 'tensor', T: Tensors, space: Tensors.Space, kind: 'tensor' }; - export type Aliased<T> = { '@type': 'aliased', T: T } & { kind: 'str' | 'int' | 'float' } + export type Tensor = { '@type': 'tensor', T: Tensors, space: Tensors.Space, valueKind: 'tensor' }; + export type Aliased<T> = { '@type': 'aliased', T: T, valueKind: 'str' | 'int' } - export const str: Str = { '@type': 'str', T: '', kind: 'str' }; - export const int: Int = { '@type': 'int', T: 0, kind: 'int' }; - export const coord: Coordinate = { '@type': 'coord', T: 0, kind: 'float' }; - export function float(precision: FloatPrecision): Float { return { '@type': 'float', T: 0, kind: 'float', precision } }; + export const str: Str = { '@type': 'str', T: '', valueKind: 'str' }; + export const int: Int = { '@type': 'int', T: 0, valueKind: 'int' }; + export const coord: Coordinate = { '@type': 'coord', T: 0, valueKind: 'float' }; + export const float: Float = { '@type': 'float', T: 0, valueKind: 'float' }; - export function tensor(space: Tensors.Space): Tensor { return { '@type': 'tensor', T: space.create(), space, kind: 'tensor' }; } + export function tensor(space: Tensors.Space): Tensor { return { '@type': 'tensor', T: space.create(), space, valueKind: 'tensor' }; } export function vector(dim: number): Tensor { return tensor(Tensors.Vector(dim)); } export function matrix(rows: number, cols: number): Tensor { return tensor(Tensors.ColumnMajorMatrix(rows, cols)); } + export function aliased<T>(t: Schema): Aliased<T> { return t as any as Aliased<T>; } } @@ -77,53 +54,53 @@ namespace Column { end?: number } - export interface LambdaSpec<T extends Type> { + export interface LambdaSpec<T extends Schema> { value: (row: number) => T['T'], rowCount: number, - type: T, + schema: T, valueKind?: (row: number) => ValueKind, } - export interface ArraySpec<T extends Type> { + export interface ArraySpec<T extends Schema> { array: ArrayLike<T['T']>, - type: T, + schema: T, valueKind?: (row: number) => ValueKind } - export interface MapSpec<S extends Type, T extends Type> { + export interface MapSpec<S extends Schema, T extends Schema> { f: (v: S['T']) => T['T'], - type: T, + schema: T, valueKind?: (row: number) => ValueKind, } export const enum ValueKind { Present = 0, NotPresent = 1, Unknown = 2 } - export function Undefined<T extends Type>(rowCount: number, type: T): Column<T['T']> { - return constColumn(type['T'], rowCount, type, ValueKind.NotPresent); + export function Undefined<T extends Schema>(rowCount: number, schema: T): Column<T['T']> { + return constColumn(schema['T'], rowCount, schema, ValueKind.NotPresent); } - export function ofConst<T extends Type>(v: T['T'], rowCount: number, type: T): Column<T['T']> { + export function ofConst<T extends Schema>(v: T['T'], rowCount: number, type: T): Column<T['T']> { return constColumn(v, rowCount, type, ValueKind.Present); } - export function ofLambda<T extends Type>(spec: LambdaSpec<T>): Column<T['T']> { + export function ofLambda<T extends Schema>(spec: LambdaSpec<T>): Column<T['T']> { return lambdaColumn(spec); } - export function ofArray<T extends Column.Type>(spec: Column.ArraySpec<T>): Column<T['T']> { + export function ofArray<T extends Column.Schema>(spec: Column.ArraySpec<T>): Column<T['T']> { return arrayColumn(spec); } export function ofIntArray(array: ArrayLike<number>) { - return arrayColumn({ array, type: Type.int }); + return arrayColumn({ array, schema: Schema.int }); } export function ofFloatArray(array: ArrayLike<number>) { - return arrayColumn({ array, type: Type.float }); + return arrayColumn({ array, schema: Schema.float }); } export function ofStringArray(array: ArrayLike<string>) { - return arrayColumn({ array, type: Type.str }); + return arrayColumn({ array, schema: Schema.str }); } export function window<T>(column: Column<T>, start: number, end: number) { @@ -150,8 +127,8 @@ namespace Column { /** Makes the column backned by an array. Useful for columns that accessed often. */ export function asArrayColumn<T>(c: Column<T>, array?: ArrayCtor<T>): Column<T> { if (c['@array']) return c; - if (!c.isDefined) return Undefined(c.rowCount, c['@type']) as any as Column<T>; - return arrayColumn({ array: c.toArray({ array }), type: c['@type'] as any, valueKind: c.valueKind }); + if (!c.isDefined) return Undefined(c.rowCount, c._schema) as any as Column<T>; + return arrayColumn({ array: c.toArray({ array }), schema: c._schema, valueKind: c.valueKind }); } } @@ -166,10 +143,10 @@ function createFirstIndexMapOfColumn<T>(c: Column<T>): Map<T, number> { return map; } -function constColumn<T extends Column.Type>(v: T['T'], rowCount: number, type: T, valueKind: Column.ValueKind): Column<T['T']> { +function constColumn<T extends Column.Schema>(v: T['T'], rowCount: number, schema: T, valueKind: Column.ValueKind): Column<T['T']> { const value: Column<T['T']>['value'] = row => v; return { - '@type': type, + _schema: schema, '@array': void 0, isDefined: valueKind === Column.ValueKind.Present, rowCount, @@ -184,9 +161,9 @@ function constColumn<T extends Column.Type>(v: T['T'], rowCount: number, type: T } } -function lambdaColumn<T extends Column.Type>({ value, valueKind, rowCount, type }: Column.LambdaSpec<T>): Column<T['T']> { +function lambdaColumn<T extends Column.Schema>({ value, valueKind, rowCount, schema }: Column.LambdaSpec<T>): Column<T['T']> { return { - '@type': type, + _schema: schema, '@array': void 0, isDefined: true, rowCount, @@ -201,21 +178,21 @@ function lambdaColumn<T extends Column.Type>({ value, valueKind, rowCount, type } } -function arrayColumn<T extends Column.Type>({ array, type, valueKind }: Column.ArraySpec<T>): Column<T['T']> { +function arrayColumn<T extends Column.Schema>({ array, schema, valueKind }: Column.ArraySpec<T>): Column<T['T']> { const rowCount = array.length; - const value: Column<T['T']>['value'] = type.kind === 'str' + const value: Column<T['T']>['value'] = schema.valueKind === 'str' ? row => { const v = array[row]; return typeof v === 'string' ? v : '' + v; } : row => array[row]; const isTyped = ColumnHelpers.isTypedArray(array); return { - '@type': type, + _schema: schema, '@array': array, isDefined: true, rowCount, value, valueKind: valueKind ? valueKind : row => Column.ValueKind.Present, - toArray: type.kind === 'str' + toArray: schema.valueKind === 'str' ? params => { const { start, end } = ColumnHelpers.getArrayBounds(rowCount, params); const ret = new (params && typeof params.array !== 'undefined' ? params.array : (array as any).constructor)(end - start) as any; @@ -239,14 +216,14 @@ function arrayColumn<T extends Column.Type>({ array, type, valueKind }: Column.A } function windowColumn<T>(column: Column<T>, start: number, end: number) { - if (!column.isDefined) return Column.Undefined(end - start, column['@type']); + if (!column.isDefined) return Column.Undefined(end - start, column._schema); if (!!column['@array'] && ColumnHelpers.isTypedArray(column['@array'])) return windowTyped(column, start, end); return windowFull(column, start, end); } function windowTyped<T>(c: Column<T>, start: number, end: number): Column<T> { const array = ColumnHelpers.typedArrayWindow(c['@array'], { start, end }); - return arrayColumn({ array, type: c['@type'], valueKind: c.valueKind }) as any; + return arrayColumn({ array, schema: c._schema, valueKind: c.valueKind }) as any; } function windowFull<T>(c: Column<T>, start: number, end: number): Column<T> { @@ -254,7 +231,7 @@ function windowFull<T>(c: Column<T>, start: number, end: number): Column<T> { const value: Column<T>['value'] = start === 0 ? v : row => v(row + start); const rowCount = end - start; return { - '@type': c['@type'], + _schema: c._schema, '@array': void 0, isDefined: c.isDefined, rowCount, @@ -288,7 +265,7 @@ function arrayView<T>(c: Column<T>, map: ArrayLike<number>): Column<T> { const array = c['@array']!; const ret = new (array as any).constructor(map.length); for (let i = 0, _i = map.length; i < _i; i++) ret[i] = array[map[i]]; - return arrayColumn({ array: ret, type: c['@type'], valueKind: c.valueKind }); + return arrayColumn({ array: ret, schema: c._schema, valueKind: c.valueKind }); } function viewFull<T>(c: Column<T>, map: ArrayLike<number>): Column<T> { @@ -296,7 +273,7 @@ function viewFull<T>(c: Column<T>, map: ArrayLike<number>): Column<T> { const value: Column<T>['value'] = row => v(map[row]); const rowCount = map.length; return { - '@type': c['@type'], + _schema: c._schema, '@array': void 0, isDefined: c.isDefined, rowCount, @@ -318,7 +295,7 @@ function mapToArrayImpl<T, S>(c: Column<T>, f: (v: T) => S, ctor: Column.ArrayCt } function areColumnsEqual(a: Column<any>, b: Column<any>) { - if (a.rowCount !== b.rowCount || a.isDefined !== b.isDefined || a['@type'].kind !== b['@type'].kind) return false; + if (a.rowCount !== b.rowCount || a.isDefined !== b.isDefined || a._schema.valueKind !== b._schema.valueKind) return false; if (!!a['@array'] && !!b['@array']) return areArraysEqual(a, b); return areValuesEqual(a, b); } diff --git a/src/mol-data/db/table.ts b/src/mol-data/db/table.ts index 65b7bd1723fc670c36d6fe4777cb2cea32ea1e60..d01629bf1650134e148ad469bcc31d37a4517cda 100644 --- a/src/mol-data/db/table.ts +++ b/src/mol-data/db/table.ts @@ -56,7 +56,7 @@ namespace Table { for (const k of columns) { (ret as any)[k] = Column.ofLambda({ rowCount, - type: schema[k], + schema: schema[k], value: r => rows[r][k], valueKind: r => typeof rows[r][k] === 'undefined' ? Column.ValueKind.NotPresent : Column.ValueKind.Present }) @@ -71,7 +71,7 @@ namespace Table { ret._columns = columns; ret._schema = schema; for (const k of columns) { - (ret as any)[k] = Column.ofArray({ array: arrays[k], type: schema[k] }) + (ret as any)[k] = Column.ofArray({ array: arrays[k], schema: schema[k] }) } return ret as R; } diff --git a/src/mol-io/reader/_spec/column.spec.ts b/src/mol-io/reader/_spec/column.spec.ts index e9e31ca993f7db515a610948d953daefcc05be52..1f7b4be1d6b753b773e2b4119742959c447adb04 100644 --- a/src/mol-io/reader/_spec/column.spec.ts +++ b/src/mol-io/reader/_spec/column.spec.ts @@ -32,8 +32,8 @@ const linesTokens = (function () { describe('fixed text column', () => { const col = FixedColumn({ data: linesData, indices: linesTokens, count: lines.length }); - const col1 = col(0, 5, Column.Type.float); - const col2 = col(5, 4, Column.Type.str); + const col1 = col(0, 5, Column.Schema.float); + const col2 = col(5, 4, Column.Schema.str); it('number', () => { expect(col1.value(0)).toBe(1.123); expect(col1.value(1)).toBe(1.0); @@ -53,7 +53,7 @@ describe('fixed text column', () => { describe('token text column', () => { const tokensData = '321'; const col = TokenColumn({ data: tokensData, indices: [0, 1, 1, 2, 2, 3], count: 3 }); - const col1 = col(Column.Type.int); + const col1 = col(Column.Schema.int); it('number', () => { expect(col1.value(0)).toBe(3); expect(col1.value(1)).toBe(2); diff --git a/src/mol-io/reader/cif/schema.ts b/src/mol-io/reader/cif/schema.ts index ef0b3f5e2d5329fd4ed6653b81e1ca811535177e..ca7b68783e53ea9057ffba4b9d40b021ec36902e 100644 --- a/src/mol-io/reader/cif/schema.ts +++ b/src/mol-io/reader/cif/schema.ts @@ -18,10 +18,10 @@ export function toTable<Schema extends Table.Schema, R extends Table<Schema> = T type ColumnCtor = (field: Data.Field, category: Data.Category, key: string) => Column<any> function getColumnCtor(t: Column.Schema): ColumnCtor { - switch (t.kind) { - case 'str': return (f, c, k) => createColumn(Column.Type.str, f, f.str, f.toStringArray); - case 'int': return (f, c, k) => createColumn(Column.Type.int, f, f.int, f.toIntArray); - case 'float': return (f, c, k) => createColumn(Column.Type.float, f, f.float, f.toFloatArray); + switch (t.valueKind) { + case 'str': return (f, c, k) => createColumn(t, f, f.str, f.toStringArray); + case 'int': return (f, c, k) => createColumn(t, f, f.int, f.toIntArray); + case 'float': return (f, c, k) => createColumn(t, f, f.float, f.toFloatArray); case 'tensor': return (f, c, k) => { const space = t.space; const value = (row: number) => Data.getTensor(c, k, space, row); @@ -31,9 +31,9 @@ function getColumnCtor(t: Column.Schema): ColumnCtor { } -function createColumn<T>(type: Column.Type, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> { +function createColumn<T>(schema: Column.Schema, field: Data.Field, value: (row: number) => T, toArray: Column<T>['toArray']): Column<T> { return { - '@type': type, + _schema: schema, '@array': field['@array'], isDefined: field.isDefined, rowCount: field.rowCount, diff --git a/src/mol-io/reader/cif/schema/dic.ts b/src/mol-io/reader/cif/schema/dic.ts index 48a73dd511b81a1ce0d0e965a81e07ede48ec2eb..07db825731e9860df7fa088af4d643128745abb8 100644 --- a/src/mol-io/reader/cif/schema/dic.ts +++ b/src/mol-io/reader/cif/schema/dic.ts @@ -7,7 +7,6 @@ import { Database, Column } from 'mol-data/db' import Schema = Column.Schema -import FP = Schema.FP const str = Schema.str; const float = Schema.float; @@ -56,7 +55,7 @@ const item_units_conversion = { from_code: str, to_code: str, operator: str, - factor: float(FP(6, 6, 6)) + factor: float } // TODO save frame dic schema diff --git a/src/mol-io/reader/cif/schema/mmcif.ts b/src/mol-io/reader/cif/schema/mmcif.ts index 5fec25ce398b79ee7b323072f505c84f9502b34e..13ff7ade995cfe73066d883b4619540f77a005ea 100644 --- a/src/mol-io/reader/cif/schema/mmcif.ts +++ b/src/mol-io/reader/cif/schema/mmcif.ts @@ -7,7 +7,6 @@ import { Database, Column } from 'mol-data/db' import Schema = Column.Schema -import FP = Schema.FP const str = Schema.str; const int = Schema.int; @@ -24,7 +23,7 @@ const entity = { type: Schema.aliased<EntityType>(str), src_method: str, pdbx_description: str, - formula_weight: float(FP(6, 3, 1)), + formula_weight: float, pdbx_number_of_molecules: int, details: str, pdbx_mutation: str, @@ -39,12 +38,12 @@ const exptl = { const cell = { entry_id: str, - length_a: float(FP(6, 6, 6)), - length_b: float(FP(6, 6, 6)), - length_c: float(FP(6, 6, 6)), - angle_alpha: float(FP(6, 6, 6)), - angle_beta: float(FP(6, 6, 6)), - angle_gamma: float(FP(6, 6, 6)), + length_a: float, + length_b: float, + length_c: float, + angle_alpha: float, + angle_beta: float, + angle_gamma: float, Z_PDB: int, pdbx_unique_axis: str } @@ -150,7 +149,7 @@ const struct_conn = { pdbx_ptnr3_label_alt_id: str, pdbx_ptnr3_PDB_ins_code: str, details: str, - pdbx_dist_value: float(FP(6, 3, 3)), + pdbx_dist_value: float, pdbx_value_order: Schema.aliased<BondValueOrder>(str) } @@ -221,8 +220,8 @@ const atom_site = { Cartn_x: Schema.coord, Cartn_y: Schema.coord, Cartn_z: Schema.coord, - occupancy: float(FP(2, 2, 1)), - B_iso_or_equiv: float(FP(2, 2, 1)), + occupancy: float, + B_iso_or_equiv: float, auth_atom_id: str, auth_comp_id: str, auth_asym_id: str, diff --git a/src/mol-io/reader/common/text/column/fixed.ts b/src/mol-io/reader/common/text/column/fixed.ts index 5b094506abc748dfd9dceebe71ffe5db76c39ca9..1026317bbccce4e4828852152775f1f416c04ae1 100644 --- a/src/mol-io/reader/common/text/column/fixed.ts +++ b/src/mol-io/reader/common/text/column/fixed.ts @@ -9,14 +9,14 @@ import { trimStr, Tokens } from '../tokenizer' import { parseIntSkipLeadingWhitespace, parseFloatSkipLeadingWhitespace } from '../number-parser' export default function FixedColumnProvider(lines: Tokens) { - return function<T extends Column.Type>(offset: number, width: number, type: T) { + return function<T extends Column.Schema>(offset: number, width: number, type: T) { return FixedColumn(lines, offset, width, type); } } -export function FixedColumn<T extends Column.Type>(lines: Tokens, offset: number, width: number, type: T): Column<T['T']> { +export function FixedColumn<T extends Column.Schema>(lines: Tokens, offset: number, width: number, schema: T): Column<T['T']> { const { data, indices, count: rowCount } = lines; - const { kind } = type; + const { valueKind: kind } = schema; const value: Column<T['T']>['value'] = kind === 'str' ? row => { let s = indices[2 * row] + offset, le = indices[2 * row + 1]; @@ -34,7 +34,7 @@ export function FixedColumn<T extends Column.Type>(lines: Tokens, offset: number return parseFloatSkipLeadingWhitespace(data, s, s + width); }; return { - '@type': type, + _schema: schema, '@array': void 0, isDefined: true, rowCount, diff --git a/src/mol-io/reader/common/text/column/token.ts b/src/mol-io/reader/common/text/column/token.ts index 21d8afd06adee270be4d38f7b5da85aa0ce96254..a0749eb595c5f37e07359d6190351bc33de2872a 100644 --- a/src/mol-io/reader/common/text/column/token.ts +++ b/src/mol-io/reader/common/text/column/token.ts @@ -9,14 +9,14 @@ import { Tokens } from '../tokenizer' import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../number-parser' export default function TokenColumnProvider(tokens: Tokens) { - return function<T extends Column.Type>(type: T) { + return function<T extends Column.Schema>(type: T) { return TokenColumn(tokens, type); } } -export function TokenColumn<T extends Column.Type>(tokens: Tokens, type: T): Column<T['T']> { +export function TokenColumn<T extends Column.Schema>(tokens: Tokens, schema: T): Column<T['T']> { const { data, indices, count: rowCount } = tokens; - const { kind } = type; + const { valueKind: kind } = schema; const value: Column<T['T']>['value'] = kind === 'str' @@ -26,7 +26,7 @@ export function TokenColumn<T extends Column.Type>(tokens: Tokens, type: T): Col : row => fastParseFloat(data, indices[2 * row], indices[2 * row + 1]) || 0; return { - '@type': type, + _schema: schema, '@array': void 0, isDefined: true, rowCount, diff --git a/src/mol-io/reader/gro/parser.ts b/src/mol-io/reader/gro/parser.ts index 47e7ea192dfe89a94abf1265e7a8770007eeb38a..d1c71ec315c3f98d47f45692838c9dfa462d4142 100644 --- a/src/mol-io/reader/gro/parser.ts +++ b/src/mol-io/reader/gro/parser.ts @@ -106,20 +106,20 @@ async function handleAtoms(state: State): Promise<Schema.Atoms> { const vW = state.header.precision.velocity + 4; const col = FixedColumn(lines); - const undef = Column.Undefined(state.numberOfAtoms, Column.Type.float); + const undef = Column.Undefined(state.numberOfAtoms, Column.Schema.float); const ret = { count: state.numberOfAtoms, - residueNumber: col(0, 5, Column.Type.int), - residueName: col(5, 5, Column.Type.str), - atomName: col(10, 5, Column.Type.str), - atomNumber: col(15, 5, Column.Type.int), - x: col(pO, pW, Column.Type.float), - y: col(pO + pW, pW, Column.Type.float), - z: col(pO + 2 * pW, pW, Column.Type.float), - vx: hasVelocities ? col(vO, vW, Column.Type.float) : undef, - vy: hasVelocities ? col(vO + vW, vW, Column.Type.float) : undef, - vz: hasVelocities ? col(vO + 2 * vW, vW, Column.Type.float) : undef, + residueNumber: col(0, 5, Column.Schema.int), + residueName: col(5, 5, Column.Schema.str), + atomName: col(10, 5, Column.Schema.str), + atomNumber: col(15, 5, Column.Schema.int), + x: col(pO, pW, Column.Schema.float), + y: col(pO + pW, pW, Column.Schema.float), + z: col(pO + 2 * pW, pW, Column.Schema.float), + vx: hasVelocities ? col(vO, vW, Column.Schema.float) : undef, + vy: hasVelocities ? col(vO + vW, vW, Column.Schema.float) : undef, + vz: hasVelocities ? col(vO + 2 * vW, vW, Column.Schema.float) : undef, }; return ret; diff --git a/src/mol-io/writer/cif/encoder.ts b/src/mol-io/writer/cif/encoder.ts index 548adbf99dc67660ecec899098a5dd9ca332081e..8654d4fc772f3460028f135b29936bfce40e7336 100644 --- a/src/mol-io/writer/cif/encoder.ts +++ b/src/mol-io/writer/cif/encoder.ts @@ -13,6 +13,7 @@ import Encoder from '../encoder' // TODO: automatically detect "best encoding" for integer arrays. This could be used for "fixed-point" as well. // TODO: add "repeat encoding"? [[1, 2], [1, 2], [1, 2]] --- Repeat ---> [[1, 2], 3] // TODO: Add "higher level fields"? (i.e. generalization of repeat) +// TODO: Add tensor field definition export const enum FieldType { Str, Int, Float @@ -29,6 +30,7 @@ export type FieldDefinition<Key = any, Data = any> = | FieldDefinitionBase<Key, Data> & { type: FieldType.Str, value(key: Key, data: Data): string } | FieldDefinitionBase<Key, Data> & { type: FieldType.Int, value(key: Key, data: Data): number } | FieldDefinitionBase<Key, Data> & { type: FieldType.Float, value(key: Key, data: Data): number } + // TODO: add tensor export interface FieldFormat { // TODO: do we actually need this? diff --git a/src/mol-model/structure/export/mmcif.ts b/src/mol-model/structure/export/mmcif.ts index c5cf31063374776b59d5030fd9a729c0642794aa..707c1049102ba64d03a62c9dd962ed8b4a1aa63d 100644 --- a/src/mol-model/structure/export/mmcif.ts +++ b/src/mol-model/structure/export/mmcif.ts @@ -49,7 +49,7 @@ function ofSchema(schema: Table.Schema) { for (const k of Object.keys(schema)) { const t = schema[k]; // TODO: matrix/vector/support - const type: any = t.kind === 'str' ? Encoder.FieldType.Str : t.kind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float; + const type: any = t.valueKind === 'str' ? Encoder.FieldType.Str : t.valueKind === 'int' ? Encoder.FieldType.Int : Encoder.FieldType.Float; fields.push({ name: k, type, value: columnValue(k), valueKind: columnValueKind(k) }) } return fields; diff --git a/src/mol-model/structure/model/formats/mmcif.ts b/src/mol-model/structure/model/formats/mmcif.ts index 24b91ee4075c5f519fe227e10081853e7e87bc29..dee0fddc23278dbb9ec3b999c3c8ff2670eb9037 100644 --- a/src/mol-model/structure/model/formats/mmcif.ts +++ b/src/mol-model/structure/model/formats/mmcif.ts @@ -40,7 +40,7 @@ function findHierarchyOffsets({ data }: mmCIF_Format, bounds: Interval) { if (newResidue) residues[residues.length] = i; if (newChain) chains[chains.length] = i; - } + } return { residues, chains }; } @@ -48,7 +48,7 @@ function createHierarchyData({ data }: mmCIF_Format, bounds: Interval, offsets: const { atom_site } = data; const start = Interval.start(bounds), end = Interval.end(bounds); const atoms = Table.ofColumns(Hierarchy.AtomsSchema, { - type_symbol: Column.ofArray({ array: Column.mapToArray(Column.window(atom_site.type_symbol, start, end), ElementSymbol), type: Column.Type.aliased<ElementSymbol>(Column.Type.str) }), + type_symbol: Column.ofArray({ array: Column.mapToArray(Column.window(atom_site.type_symbol, start, end), ElementSymbol), schema: Column.Schema.aliased<ElementSymbol>(Column.Schema.str) }), label_atom_id: Column.window(atom_site.label_atom_id, start, end), auth_atom_id: Column.window(atom_site.auth_atom_id, start, end), label_alt_id: Column.window(atom_site.label_alt_id, start, end), diff --git a/src/perf-tests/column.ts b/src/perf-tests/column.ts index 88ad89b351094374c876a1471a1a8f54e746c720..bc1dda619ce874501bce1cfec13bb4aa8f849f1f 100644 --- a/src/perf-tests/column.ts +++ b/src/perf-tests/column.ts @@ -40,9 +40,9 @@ export namespace Column { const suite = new B.Suite(); const data = createData(1000); const nativeData = [...data as any]; - const col = C.ofArray({ array: data, type: C.Type.float }); - const lambda = C.ofLambda({ value: val, rowCount: data.length, type: C.Type.float }); - const cnst = C.ofConst(10, data.length, C.Type.float); + const col = C.ofArray({ array: data, schema: C.Schema.float }); + const lambda = C.ofLambda({ value: val, rowCount: data.length, schema: C.Schema.float }); + const cnst = C.ofConst(10, data.length, C.Schema.float); suite .add('raw', () => raw(data)) .add('native raw', () => raw(nativeData)) @@ -59,9 +59,9 @@ export namespace Column { const suite = new B.Suite(); const data = createData(10000); const nativeData = [...data as any]; - const col = C.ofArray({ array: data, type: C.Type.float }); - const lambda = C.ofLambda({ value: val, rowCount: data.length, type: C.Type.float }); - const cnst = C.ofConst(10, data.length, C.Type.float); + const col = C.ofArray({ array: data, schema: C.Schema.float }); + const lambda = C.ofLambda({ value: val, rowCount: data.length, schema: C.Schema.float }); + const cnst = C.ofConst(10, data.length, C.Schema.float); suite .add('raw', () => raw(data)) .add('native raw', () => raw(nativeData))