Browse Source

various stuff

David Sehnal 7 years ago
parent
commit
a3246a58b1

+ 1 - 0
src/mol-base/collections/integer/impl/ordered-set.ts

@@ -14,6 +14,7 @@ export const Empty: OrderedSetImpl = I.Empty;
 
 export const ofSingleton = I.ofSingleton
 export const ofRange = I.ofRange
+export const ofBounds = I.ofBounds
 
 export function ofSortedArray(xs: Nums): OrderedSetImpl {
     if (!xs.length) return Empty;

+ 1 - 0
src/mol-base/collections/integer/ordered-set.ts

@@ -11,6 +11,7 @@ namespace OrderedSet {
     export const Empty: OrderedSet = Base.Empty as any;
     export const ofSingleton: (value: number) => OrderedSet = Base.ofSingleton as any;
     export const ofRange: (min: number, max: number) => OrderedSet = Base.ofRange as any;
+    export const ofBounds: (min: number, max: number) => OrderedSet = Base.ofBounds as any;
     /** It is the responsibility of the caller to ensure the array is sorted and contains unique values. */
     export const ofSortedArray: (xs: ArrayLike<number>) => OrderedSet = Base.ofSortedArray as any;
 

+ 1 - 0
src/mol-base/collections/integer/segmentation.ts

@@ -24,6 +24,7 @@ namespace Segmentation {
 
 interface Segmentation {
     '@type': 'segmentation',
+    readonly segments: ArrayLike<number>,
     readonly segmentMap: ArrayLike<number>,
     readonly count: number
 }

+ 3 - 17
src/mol-base/computation.ts

@@ -5,7 +5,8 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Scheduler from './scheduler'
+import Scheduler from './utils/scheduler'
+import timeNow from './utils/time'
 
 interface Computation<A> {
     (ctx?: Computation.Context): Promise<A>
@@ -79,22 +80,7 @@ namespace Computation {
         return ret;
     }
 
-    declare var process: any;
-    declare var window: any;
-
-    export const now: () => number = (function () {
-        if (typeof window !== 'undefined' && window.performance) {
-            const perf = window.performance;
-            return () => perf.now();
-        } else if (typeof process !== 'undefined' && process.hrtime !== 'undefined') {
-            return () => {
-                let t = process.hrtime();
-                return t[0] * 1000 + t[1] / 1000000;
-            };
-        } else {
-            return () => +new Date();
-        }
-    }());
+    export const now = timeNow;
 
     /** A utility for splitting large computations into smaller parts. */
     export interface Chunker {

+ 0 - 0
src/mol-base/scheduler.ts → src/mol-base/utils/scheduler.ts


+ 24 - 0
src/mol-base/utils/time.ts

@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+declare var process: any;
+declare var window: any;
+
+const now: () => number = (function () {
+    if (typeof window !== 'undefined' && window.performance) {
+        const perf = window.performance;
+        return () => perf.now();
+    } else if (typeof process !== 'undefined' && process.hrtime !== 'undefined') {
+        return () => {
+            let t = process.hrtime();
+            return t[0] * 1000 + t[1] / 1000000;
+        };
+    } else {
+        return () => +new Date();
+    }
+}());
+
+export default now;

+ 17 - 0
src/mol-base/utils/uuid.ts

@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import now from './time'
+
+export default function generateUUID() {
+    let d = now();
+    const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+        const r = (d + Math.random()*16)%16 | 0;
+        d = Math.floor(d/16);
+        return (c==='x' ? r : (r&0x3|0x8)).toString(16);
+    });
+    return uuid;
+}

+ 2 - 2
src/mol-data/_spec/atom-set.spec.ts

@@ -5,8 +5,8 @@
  */
 
 import OrderedSet from '../../mol-base/collections/integer/ordered-set'
-import AtomSet from '../atom-set'
-import Atom from '../atom'
+import AtomSet from '../structure/atom-set'
+import Atom from '../structure/atom'
 
 describe('atom set', () => {
     const p = (i: number, j: number) => Atom.create(i, j);

+ 14 - 4
src/mol-data/model.ts

@@ -5,8 +5,9 @@
  */
 
 import * as Formats from './model/formats'
-import CommonInterface from './model/common'
-import MacromoleculeInterface from './model/macromolecule'
+import CommonProperties from './model/common'
+import MacromoleculeProperties from './model/macromolecule'
+import Conformation from './model/conformation'
 import Segmentation from '../mol-base/collections/integer/segmentation'
 
 /**
@@ -15,10 +16,19 @@ import Segmentation from '../mol-base/collections/integer/segmentation'
  * "Atoms" are integers in the range [0, atomCount).
  */
 interface Model extends Readonly<{
+    id: string,
+
     sourceData: Formats.RawData,
 
-    common: CommonInterface,
-    macromolecule: MacromoleculeInterface
+    common: CommonProperties,
+    macromolecule: MacromoleculeProperties,
+    conformation: Conformation,
+
+    // used for diffing.
+    version: {
+        data: number,
+        conformation: number
+    },
 
     atomCount: number,
     segments: Readonly<{

+ 7 - 2
src/mol-data/model/builders/mmcif.ts

@@ -9,6 +9,7 @@ import mmCIF from '../../../mol-io/reader/cif/schema/mmcif'
 import Model from '../../model'
 import Interval from '../../../mol-base/collections/integer/interval'
 import Segmentation from '../../../mol-base/collections/integer/segmentation'
+import uuId from '../../../mol-base/utils/uuid'
 
 function findModelBounds(data: mmCIF, startIndex: number) {
     const num = data.atom_site.pdbx_PDB_model_num;
@@ -23,7 +24,7 @@ function segment(data: mmCIF, bounds: Interval) {
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const residues = [0], chains = [0], entities = [0];
 
-    const { label_entity_id, auth_asym_id, auth_seq_id, pdbx_PDB_ins_code } = data.atom_site;
+    const { label_entity_id, auth_asym_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = data.atom_site;
 
     let offset = 1;
     for (let i = start + 1; i < end; i++) {
@@ -31,7 +32,8 @@ function segment(data: mmCIF, bounds: Interval) {
         const newChain = newEntity || !auth_asym_id.areValuesEqual(i - 1, i);
         const newResidue = newChain
             || !auth_seq_id.areValuesEqual(i - 1, i)
-            || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i);
+            || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
+            || !label_comp_id.areValuesEqual(i - 1, i);
 
         if (newEntity) entities[entities.length] = offset;
         if (newResidue) residues[residues.length] = offset;
@@ -53,9 +55,12 @@ function segment(data: mmCIF, bounds: Interval) {
 function createModel(raw: RawData, data: mmCIF, bounds: Interval): Model {
     const segments = segment(data, bounds);
     return {
+        id: uuId(),
         sourceData: raw,
         common: 0 as any,
         macromolecule: 0 as any,
+        conformation: 0 as any,
+        version: { data: 0, conformation: 0 },
         atomCount: Interval.size(bounds),
         segments
     };

+ 0 - 0
src/mol-data/conformation.ts → src/mol-data/model/conformation.ts


+ 8 - 36
src/mol-data/structure.ts

@@ -4,41 +4,12 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Vec3, Mat4 } from '../mol-base/math/linear-algebra'
-import AtomSet from './atom-set'
-import Model from './model'
-import Conformation from './conformation'
-
-export interface Operator extends Readonly<{
-    name: string,
-    hkl: number[], // defaults to [0, 0, 0] for non symmetry entries
-    transform: Mat4,
-    // cache the inverse of the transform
-    inverse: Mat4,
-    // optimize the identity case
-    isIdentity: boolean
-}> { }
-
-export interface Unit extends Readonly<{
-    // Structure-level unique identifier of the unit.
-    id: number,
-
-    // Provides access to the underlying data.
-    model: Model,
-
-    // Separate the conformation from the data for faster/more straightforward dynamics
-    conformation: Conformation,
-
-    // Determines the operation applied to this unit.
-    // The transform and and inverse are baked into the "getPosition" function
-    operator: Operator
-}> {
-    // returns the untransformed position. Used for spatial queries.
-    getInvariantPosition(atom: number, slot: Vec3): Vec3
-
-    // gets the transformed position of the specified atom
-    getPosition(atom: number, slot: Vec3): Vec3
-}
+//import { Vec3 } from '../mol-base/math/linear-algebra'
+import AtomSet from './structure/atom-set'
+import Unit from './structure/unit'
+import * as Base from './structure/base'
+//import Model from './model'
+//import Operator from './structure/operator'
 
 // TODO: do "single model" version of the structure?
 export interface Structure extends Readonly<{
@@ -47,7 +18,8 @@ export interface Structure extends Readonly<{
 }> { }
 
 export namespace Structure {
-    export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
+    export const Empty = Base.Empty;
+    export const ofModel = Base.ofModel;
 
     // TODO: "lift" atom set operators
     // TODO: "diff"

+ 2 - 2
src/mol-data/atom-set.ts → src/mol-data/structure/atom-set.ts

@@ -4,8 +4,8 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import OrderedSet from '../mol-base/collections/integer/ordered-set'
-import Iterator from '../mol-base/collections/iterator'
+import OrderedSet from '../../mol-base/collections/integer/ordered-set'
+import Iterator from '../../mol-base/collections/iterator'
 import Atom from './atom'
 import * as Base from './atom-set/base'
 import createBuilder from './atom-set/builder'

+ 5 - 5
src/mol-data/atom-set/base.ts → src/mol-data/structure/atom-set/base.ts

@@ -4,11 +4,11 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import OrderedSet from '../../mol-base/collections/integer/ordered-set'
-import Iterator from '../../mol-base/collections/iterator'
-import Interval from '../../mol-base/collections/integer/interval'
-import { sortArray } from '../../mol-base/collections/sort'
-import { hash1 } from '../../mol-base/collections/hash-functions'
+import OrderedSet from '../../../mol-base/collections/integer/ordered-set'
+import Iterator from '../../../mol-base/collections/iterator'
+import Interval from '../../../mol-base/collections/integer/interval'
+import { sortArray } from '../../../mol-base/collections/sort'
+import { hash1 } from '../../../mol-base/collections/hash-functions'
 import Atom from '../atom'
 
 /** Long and painful implementation starts here */

+ 2 - 2
src/mol-data/atom-set/builder.ts → src/mol-data/structure/atom-set/builder.ts

@@ -5,8 +5,8 @@
  */
 
 import AtomSet from '../atom-set'
-import OrderedSet from '../../mol-base/collections/integer/ordered-set'
-import { sortArray } from '../../mol-base/collections/sort'
+import OrderedSet from '../../../mol-base/collections/integer/ordered-set'
+import { sortArray } from '../../../mol-base/collections/sort'
 
 class Builder {
     private keys: number[] = [];

+ 0 - 0
src/mol-data/atom-set/properties.ts → src/mol-data/structure/atom-set/properties.ts


+ 1 - 1
src/mol-data/atom.ts → src/mol-data/structure/atom.ts

@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Tuple from '../mol-base/collections/integer/tuple'
+import Tuple from '../../mol-base/collections/integer/tuple'
 
 /** Atom pointer */
 interface Atom { '@type': Tuple['@type'] }

+ 25 - 3
src/mol-data/structure/base.ts

@@ -6,10 +6,32 @@
 
 import Model from '../model'
 import Structure from '../structure'
+import Unit from './unit'
+import Operator from './operator'
+import AtomSet from './atom-set'
+import OrderedSet from '../../mol-base/collections/integer/ordered-set'
 
-//export const Empty { }
+class Builder {
+    private units = Object.create(null);
+    private atoms = Object.create(null);
+
+    addUnit(unit: Unit) { this.units[unit.id] = unit; }
+    addAtoms(unitId: number, atoms: OrderedSet) { this.atoms[unitId] = atoms; }
+
+    getStructure(): Structure { return { units: this.units, atoms: AtomSet.create(this.atoms) } }
+}
+
+export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
 
 export function ofModel(model: Model): Structure {
-    // TODO: create a unit for each chain in the model
-    return 0 as any;
+    const chains = model.segments.chains;
+    const builder = new Builder();
+
+    for (let c = 0; c < chains.count; c++) {
+        const unit = Unit.create(model, Operator.Identity);
+        builder.addUnit(unit);
+        builder.addAtoms(unit.id, OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1]));
+    }
+
+    return builder.getStructure();
 }

+ 23 - 0
src/mol-data/structure/operator.ts

@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { Mat4 } from '../../mol-base/math/linear-algebra'
+
+interface Operator extends Readonly<{
+    name: string,
+    hkl: number[], // defaults to [0, 0, 0] for non symmetry entries
+    transform: Mat4,
+    // cache the inverse of the transform
+    inverse: Mat4,
+    // optimize the identity case
+    isIdentity: boolean
+}> { }
+
+namespace Operator {
+    export const Identity: Operator = { name: '1_555', hkl: [0, 0, 0], transform: Mat4.identity(), inverse: Mat4.identity(), isIdentity: true };
+}
+
+export default Operator

+ 41 - 0
src/mol-data/structure/unit.ts

@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import Model from '../model'
+import Operator from './operator'
+
+interface Unit extends Readonly<{
+    // Structure-level unique identifier of the unit.
+    id: number,
+
+    // Provides access to the underlying data.
+    model: Model,
+
+    // Determines the operation applied to this unit.
+    // The transform and and inverse are baked into the "getPosition" function
+    operator: Operator
+}> {
+    // // returns the untransformed position. Used for spatial queries.
+    // getInvariantPosition(atom: number, slot: Vec3): Vec3
+
+    // // gets the transformed position of the specified atom
+    // getPosition(atom: number, slot: Vec3): Vec3
+}
+
+namespace Unit {
+    export function create(model: Model, operator: Operator): Unit {
+        return { id: nextUnitId(), model, operator };
+    }
+}
+
+export default Unit;
+
+let _id = 0;
+function nextUnitId() {
+    const ret = _id;
+    _id = (_id + 1) % 0x3fffffff;
+    return ret;
+}

+ 8 - 6
src/perf-tests/sets.ts

@@ -1,7 +1,7 @@
 import * as B from 'benchmark'
 import Tuple from '../mol-base/collections/integer/tuple'
 import OrdSet from '../mol-base/collections/integer/ordered-set'
-import AtomSet from '../mol-data/atom-set'
+import AtomSet from '../mol-data/structure/atom-set'
 import Segmentation from '../mol-base/collections/integer/segmentation'
 
 export namespace Iteration {
@@ -203,8 +203,8 @@ export namespace Union {
 export namespace Build {
     function createSorted() {
         const b = AtomSet.SortedBuilder(AtomSet.Empty);
-        for (let i = 0; i < 100; i++) {
-            for (let j = 0; j < 100; j++) {
+        for (let i = 0; i < 10; i++) {
+            for (let j = 0; j < 1000; j++) {
                 b.add(i, j);
             }
         }
@@ -213,9 +213,9 @@ export namespace Build {
 
     function createByUnit() {
         const b = AtomSet.SortedBuilder(AtomSet.Empty);
-        for (let i = 0; i < 100; i++) {
+        for (let i = 0; i < 10; i++) {
             b.beginUnit();
-            for (let j = 0; j < 100; j++) {
+            for (let j = 0; j < 1000; j++) {
                 b.addToUnit(j);
             }
             b.commitUnit(i);
@@ -284,7 +284,9 @@ export function testSegments() {
     }
 }
 
-testSegments();
+Build.run();
+
+//testSegments();
 
 //Tuples.run();