From ecb0f8c4a331793a7dbe037eb5b8baf3e38c7008 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Mon, 30 Oct 2017 22:37:10 +0100
Subject: [PATCH] tables and data model

---
 src/mol-base/collections/_spec/table.spec.ts             | 7 ++++---
 src/mol-base/collections/table.ts                        | 9 +++++++--
 src/mol-data/model.ts                                    | 4 ++--
 .../properties/{hierarchy.ts => macromolecule-tree.ts}   | 4 ++--
 4 files changed, 15 insertions(+), 9 deletions(-)
 rename src/mol-data/model/properties/{hierarchy.ts => macromolecule-tree.ts} (95%)

diff --git a/src/mol-base/collections/_spec/table.spec.ts b/src/mol-base/collections/_spec/table.spec.ts
index 35eaacb85..81d1733cc 100644
--- a/src/mol-base/collections/_spec/table.spec.ts
+++ b/src/mol-base/collections/_spec/table.spec.ts
@@ -83,11 +83,12 @@ 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 picked = Table.pickColumns(s, t);
-        expect(picked._columns).toEqual(['x']);
+        const s = { x: Column.Type.int, y: Column.Type.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);
         expect(picked.x.toArray()).toEqual([10, -1]);
+        expect(picked.y.toArray()).toEqual([3, 4]);
     });
 
     it('sort', () => {
diff --git a/src/mol-base/collections/table.ts b/src/mol-base/collections/table.ts
index a7f7aed5a..087edc66b 100644
--- a/src/mol-base/collections/table.ts
+++ b/src/mol-base/collections/table.ts
@@ -15,13 +15,18 @@ namespace Table {
     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']> }
+    export type PartialTable<S extends Table.Schema> = { readonly _rowCount: number, readonly _columns: ReadonlyArray<string> } & { [C in keyof S]?: Column<S[C]['T']> }
 
-    export function pickColumns<S extends Schema, T extends S>(schema: S, table: Table<T>): Table<S> {
+    export function pickColumns<S extends Schema>(schema: S, table: PartialTable<S>, guard: Partial<Columns<S>> = {}): Table<S> {
         const ret = Object.create(null);
         const keys = Object.keys(schema);
         ret._rowCount = table._rowCount;
         ret._columns = keys;
-        for (const k of keys) ret[k] = table[k];
+        for (const k of keys) {
+            if (!!table[k]) ret[k] = table[k];
+            else if (!!guard[k]) ret[k] = guard[k];
+            else throw Error(`Cannot find column '${k}'.`);
+        }
         return ret;
     }
 
diff --git a/src/mol-data/model.ts b/src/mol-data/model.ts
index 3572e7618..a9e450a0a 100644
--- a/src/mol-data/model.ts
+++ b/src/mol-data/model.ts
@@ -6,7 +6,7 @@
 
 import * as Formats from './model/formats'
 //import CommonProperties from './model/properties/common'
-import HierarchyProperties from './model/properties/hierarchy'
+import MacromoleculeTree from './model/properties/macromolecule-tree'
 import Conformation from './model/properties/conformation'
 import Segmentation from '../mol-base/collections/integer/segmentation'
 
@@ -23,7 +23,7 @@ interface Model extends Readonly<{
     sourceData: Formats.RawData,
 
     //common: CommonProperties,
-    macromolecule: HierarchyProperties,
+    macromolecule: MacromoleculeTree,
     conformation: Conformation,
 
     // used for diffing.
diff --git a/src/mol-data/model/properties/hierarchy.ts b/src/mol-data/model/properties/macromolecule-tree.ts
similarity index 95%
rename from src/mol-data/model/properties/hierarchy.ts
rename to src/mol-data/model/properties/macromolecule-tree.ts
index 5d54f59ba..73728868e 100644
--- a/src/mol-data/model/properties/hierarchy.ts
+++ b/src/mol-data/model/properties/macromolecule-tree.ts
@@ -8,10 +8,10 @@ import Column from '../../../mol-base/collections/column'
 import Table from '../../../mol-base/collections/table'
 import { Schema as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
 
+const _esCache = Object.create(null);
 export interface ElementSymbol extends String { '@type': 'element-symbol' }
 export function ElementSymbol(s: string): ElementSymbol {
-    // TODO: optimize?
-    return s.toUpperCase() as any;
+    return _esCache[s] || (_esCache[s] = s.toUpperCase());
 }
 
 export const AtomsSchema = {
-- 
GitLab