From 088e61bccffe4cad07fbaa01c8f85399eb649048 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Sun, 5 Nov 2017 18:47:10 +0100
Subject: [PATCH] include float precision in table schemas

---
 src/apps/domain-annotation-server/schemas.ts  |  2 +-
 .../collections/database/_spec/table.spec.ts  |  8 +--
 src/mol-base/collections/database/column.ts   | 29 +++++++++++
 src/mol-base/collections/database/table.ts    |  2 +-
 .../structure/model/properties/hierarchy.ts   |  2 +-
 src/mol-io/reader/_spec/cif.spec.ts           |  2 +-
 src/mol-io/reader/cif/schema.ts               |  2 +-
 src/mol-io/reader/cif/schema/dic.ts           |  9 ++--
 src/mol-io/reader/cif/schema/mmcif.ts         | 52 ++++++++++---------
 9 files changed, 70 insertions(+), 38 deletions(-)

diff --git a/src/apps/domain-annotation-server/schemas.ts b/src/apps/domain-annotation-server/schemas.ts
index 34f17d566..90bbcba97 100644
--- a/src/apps/domain-annotation-server/schemas.ts
+++ b/src/apps/domain-annotation-server/schemas.ts
@@ -6,7 +6,7 @@
 
 import { Column } from 'mol-base/collections/database'
 
-import Type = Column.Type
+import Type = Column.Schema
 
 export const Sources = {
     id: Type.str,
diff --git a/src/mol-base/collections/database/_spec/table.spec.ts b/src/mol-base/collections/database/_spec/table.spec.ts
index 69e534231..9f61d1baf 100644
--- a/src/mol-base/collections/database/_spec/table.spec.ts
+++ b/src/mol-base/collections/database/_spec/table.spec.ts
@@ -53,8 +53,8 @@ describe('column', () => {
 
 describe('table', () => {
     const schema = {
-        x: Column.Type.int,
-        n: Column.Type.str
+        x: Column.Schema.int,
+        n: Column.Schema.str
     };
 
     it('ofRows', () => {
@@ -89,7 +89,7 @@ describe('table', () => {
             x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
             n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }),
         });
-        const s = { x: Column.Type.int, y: Column.Type.int };
+        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 })});
         expect(picked._columns).toEqual(['x', 'y']);
         expect(picked._rowCount).toEqual(2);
@@ -102,7 +102,7 @@ describe('table', () => {
             x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
             n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }),
         });
-        const s = { x: Column.Type.int };
+        const s = { x: Column.Schema.int };
         const view = Table.view(t, s, [1]);
         expect(view._columns).toEqual(['x']);
         expect(view._rowCount).toEqual(1);
diff --git a/src/mol-base/collections/database/column.ts b/src/mol-base/collections/database/column.ts
index 80b9fc94c..a6110269f 100644
--- a/src/mol-base/collections/database/column.ts
+++ b/src/mol-base/collections/database/column.ts
@@ -39,6 +39,35 @@ namespace Column {
         export function aliased<T>(t: Type): Aliased<T> { return t as any as Aliased<T>; }
     }
 
+    export type Schema<T = any> = Schema.Scalar | Schema.Vector | Schema.Matrix | Schema.Aliased<T>
+
+    export namespace Schema {
+        export interface FloatPrecision {
+            low: number,
+            acceptable: number,
+            full: number
+        }
+
+        export type Scalar = Schema.Str | Schema.Int | Schema.Float
+
+        export function FP(full: number, acceptable: number, low: number): FloatPrecision { return { low, full, acceptable }; }
+
+        export type Str = { '@type': 'schema', T: string, kind: 'str' }
+        export type Int = { '@type': 'schema', T: number, kind: 'int' }
+        export type Float = { '@type': 'schema', T: number, kind: 'float', precision: FloatPrecision }
+        export type Vector = { '@type': 'schema', T: number[], dim: number, kind: 'vector' };
+        export type Matrix = { '@type': 'schema', T: number[][], rows: number, cols: number, kind: 'matrix' };
+        export type Aliased<T> = { '@type': 'schema', T: T } & { kind: 'str' | 'int' | 'float' }
+
+        export const str: Str = { '@type': 'schema', T: '', kind: 'str' };
+        export const int: Int = { '@type': 'schema', T: 0, kind: 'int' };
+        export function float(precision: FloatPrecision): Float { return { '@type': 'schema', T: 0, kind: 'float', precision } };
+
+        export function vector(dim: number): Vector { return { '@type': 'schema', T: [] as number[], dim, kind: 'vector' }; }
+        export function matrix(rows: number, cols: number): Matrix { return { '@type': 'schema', T: [] as number[][], rows, cols, kind: 'matrix' }; }
+        export function aliased<T>(t: Schema): Aliased<T> { return t as any as Aliased<T>; }
+    }
+
     export interface ToArrayParams<T> {
         array?: ArrayCtor<T>,
         start?: number,
diff --git a/src/mol-base/collections/database/table.ts b/src/mol-base/collections/database/table.ts
index fa701fa39..a7178bc1c 100644
--- a/src/mol-base/collections/database/table.ts
+++ b/src/mol-base/collections/database/table.ts
@@ -16,7 +16,7 @@ type Table<Schema extends Table.Schema> = {
 
 /** An immutable table */
 namespace Table {
-    export type Schema = { [field: string]: Column.Type }
+    export type Schema = { [field: string]: Column.Schema }
     export type Columns<S extends Schema> = { [C in keyof S]: Column<S[C]['T']> }
     export type Row<S extends Schema> = { [C in keyof S]: S[C]['T'] }
     export type Arrays<S extends Schema> = { [C in keyof S]: ArrayLike<S[C]['T']> }
diff --git a/src/mol-data/structure/model/properties/hierarchy.ts b/src/mol-data/structure/model/properties/hierarchy.ts
index fa647d207..a19de7fd5 100644
--- a/src/mol-data/structure/model/properties/hierarchy.ts
+++ b/src/mol-data/structure/model/properties/hierarchy.ts
@@ -10,7 +10,7 @@ import { mmCIF_Schema as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
 import { ElementSymbol} from '../types'
 
 export const AtomsSchema = {
-    type_symbol: Column.Type.aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
+    type_symbol: Column.Schema.aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
     label_atom_id: mmCIF.atom_site.label_atom_id,
     auth_atom_id: mmCIF.atom_site.auth_atom_id,
     label_alt_id: mmCIF.atom_site.label_alt_id,
diff --git a/src/mol-io/reader/_spec/cif.spec.ts b/src/mol-io/reader/_spec/cif.spec.ts
index b2309f006..856e1e16f 100644
--- a/src/mol-io/reader/_spec/cif.spec.ts
+++ b/src/mol-io/reader/_spec/cif.spec.ts
@@ -22,7 +22,7 @@ const testBlock = Data.Block(['atoms'], {
 }, 'test');
 
 namespace TestSchema {
-    export const atoms = { x: Column.Type.int, name: Column.Type.str }
+    export const atoms = { x: Column.Schema.int, name: Column.Schema.str }
     export const schema = { atoms }
 }
 
diff --git a/src/mol-io/reader/cif/schema.ts b/src/mol-io/reader/cif/schema.ts
index ee788fdfd..3c8c40214 100644
--- a/src/mol-io/reader/cif/schema.ts
+++ b/src/mol-io/reader/cif/schema.ts
@@ -17,7 +17,7 @@ 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.Type): ColumnCtor {
+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);
diff --git a/src/mol-io/reader/cif/schema/dic.ts b/src/mol-io/reader/cif/schema/dic.ts
index 09e0d5b60..f9a934abd 100644
--- a/src/mol-io/reader/cif/schema/dic.ts
+++ b/src/mol-io/reader/cif/schema/dic.ts
@@ -5,11 +5,12 @@
  */
 
 import { Database, Column } from 'mol-base/collections/database'
-import Types = Column.Type
 
+import Schema = Column.Schema
+import FP = Schema.FP
 
-const str = Types.str
-const float = Types.float
+const str = Schema.str;
+const float = Schema.float;
 
 const datablock = {
     id: str,
@@ -55,7 +56,7 @@ const item_units_conversion = {
     from_code: str,
     to_code: str,
     operator: str,
-    factor: float
+    factor: float(FP(6, 6, 6))
 }
 
 // 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 42aabd396..939c9039e 100644
--- a/src/mol-io/reader/cif/schema/mmcif.ts
+++ b/src/mol-io/reader/cif/schema/mmcif.ts
@@ -5,11 +5,13 @@
  */
 
 import { Database, Column } from 'mol-base/collections/database'
-import Types = Column.Type
 
-const str = Types.str;
-const int = Types.int;
-const float = Types.float;
+import Schema = Column.Schema
+import FP = Schema.FP
+
+const str = Schema.str;
+const int = Schema.int;
+const float = Schema.float;
 
 const entry = {
     id: str
@@ -19,10 +21,10 @@ type EntityType = 'polymer' | 'non-polymer' | 'water' | 'macrolide'
 
 const entity = {
     id: str,
-    type: Types.aliased<EntityType>(str),
+    type: Schema.aliased<EntityType>(str),
     src_method: str,
     pdbx_description: str,
-    formula_weight: float,
+    formula_weight: float(FP(6, 3, 1)),
     pdbx_number_of_molecules: int,
     details: str,
     pdbx_mutation: str,
@@ -37,12 +39,12 @@ const exptl = {
 
 const cell = {
     entry_id: str,
-    length_a: float,
-    length_b: float,
-    length_c: float,
-    angle_alpha: float,
-    angle_beta: float,
-    angle_gamma: float,
+    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)),
     Z_PDB: int,
     pdbx_unique_axis: str
 }
@@ -118,7 +120,7 @@ type BondValueOrder =
 
 const struct_conn = {
     id: str,
-    conn_type_id: Types.aliased<StructConnTypeId>(str),
+    conn_type_id: Schema.aliased<StructConnTypeId>(str),
     pdbx_PDB_id: str,
     ptnr1_label_asym_id: str,
     ptnr1_label_comp_id: str,
@@ -148,12 +150,12 @@ const struct_conn = {
     pdbx_ptnr3_label_alt_id: str,
     pdbx_ptnr3_PDB_ins_code: str,
     details: str,
-    pdbx_dist_value: float,
-    pdbx_value_order: Types.aliased<BondValueOrder>(str)
+    pdbx_dist_value: float(FP(6, 3, 3)),
+    pdbx_value_order: Schema.aliased<BondValueOrder>(str)
 }
 
 const struct_conn_type = {
-    id: Types.aliased<StructConnTypeId>(str),
+    id: Schema.aliased<StructConnTypeId>(str),
     criteria: str,
     reference: str
 }
@@ -162,10 +164,10 @@ const chem_comp_bond = {
     comp_id: str,
     pdbx_stereo_config: str,
     pdbx_ordinal: int,
-    pdbx_aromatic_flag: Types.aliased<'Y' | 'N'>(str),
+    pdbx_aromatic_flag: Schema.aliased<'Y' | 'N'>(str),
     atom_id_1: str,
     atom_id_2: str,
-    value_order: Types.aliased<BondValueOrder>(str)
+    value_order: Schema.aliased<BondValueOrder>(str)
 }
 
 const pdbx_struct_assembly = {
@@ -187,8 +189,8 @@ const pdbx_struct_oper_list = {
     type: str,
     name: str,
     symmetry_operation: str,
-    matrix: Types.matrix(3, 3),
-    vector: Types.vector(3)
+    matrix: Schema.matrix(3, 3),
+    vector: Schema.vector(3)
 }
 
 const pdbx_struct_mod_residue = {
@@ -216,11 +218,11 @@ const atom_site = {
     label_seq_id: int,
     pdbx_PDB_ins_code: str,
     pdbx_formal_charge: str,
-    Cartn_x: float,
-    Cartn_y: float,
-    Cartn_z: float,
-    occupancy: float,
-    B_iso_or_equiv: float,
+    Cartn_x: float(FP(6, 3, 1)),
+    Cartn_y: float(FP(6, 3, 1)),
+    Cartn_z: float(FP(6, 3, 1)),
+    occupancy: float(FP(2, 2, 1)),
+    B_iso_or_equiv: float(FP(2, 2, 1)),
     auth_atom_id: str,
     auth_comp_id: str,
     auth_asym_id: str,
-- 
GitLab