Browse Source

refactoring

David Sehnal 7 years ago
parent
commit
ed28bf3d36

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

@@ -248,7 +248,7 @@ function subtractIS(a: I, b: S) {
     let offset = 0;
     for (let i = min; i < fst; i++) ret[offset++] = i;
     for (let i = fst; i <= last; i++) {
-        if (S.indexOfInterval(b, i, interval) < 0) ret[offset++] = i;
+        if (S.indexOfInInterval(b, i, interval) < 0) ret[offset++] = i;
     }
     for (let i = last + 1; i <= max; i++) ret[offset++] = i;
     return ofSortedArray(ret);

+ 1 - 1
src/mol-base/collections/integer/impl/sorted-array.ts

@@ -35,7 +35,7 @@ export function indexOf(xs: Nums, v: number) {
     const l = xs.length;
     return l === 0 ? -1 : xs[0] <= v && v <= xs[l - 1] ? binarySearchRange(xs, v, 0, l) : -1;
 }
-export function indexOfInterval(xs: Nums, v: number, bounds: Interval) {
+export function indexOfInInterval(xs: Nums, v: number, bounds: Interval) {
     const l = xs.length;
     const s = Interval.start(bounds), e = Interval.end(bounds);
     return l === 0 || e <= s ? -1 : xs[s] <= v && v <= xs[e - 1] ? binarySearchRange(xs, v, s, e) : -1;

+ 1 - 2
src/mol-base/collections/integer/sorted-array.ts

@@ -16,8 +16,7 @@ namespace SortedArray {
 
     export const has: (array: SortedArray, x: number) => boolean = Impl.has as any;
     export const indexOf: (array: SortedArray, x: number) => number = Impl.indexOf as any;
-    export const indexOfInterval: (array: SortedArray, x: number, bounds: Interval) => number = Impl.indexOfInterval as any;
-    //export const getAt: (array: SortedArray, i: number) => number = Impl.getAt as any;
+    export const indexOfInInterval: (array: SortedArray, x: number, bounds: Interval) => number = Impl.indexOfInInterval as any;
 
     export const start: (array: SortedArray) => number = Impl.start as any;
     export const end: (array: SortedArray) => number = Impl.end as any;

+ 2 - 4
src/mol-base/collections/iterator.ts

@@ -5,12 +5,10 @@
  */
 
 /**
- * ES6 compatible iterator.
- *
- * "Idiomatic" usage is to use the move function, because it does not make any allocations.
+ * "Idiomatic" usage:
  *
  * const it = ...;
- * while (it.hasNext) { const v = it.move(); ... } 
+ * while (it.hasNext) { const v = it.move(); ... }
  */
 interface Iterator<T> {
     readonly hasNext: boolean,

+ 4 - 0
src/mol-base/utils/bit-flags.ts

@@ -7,7 +7,11 @@
 interface BitFlags<Flags> { '@type': Flags }
 
 namespace BitFlags {
+    export function create<F>(flags: F): BitFlags<F> { return flags as any; }
+
     export function has<F>(flags: BitFlags<F>, flag: F) { return ((flags as any) & (flag as any)) !== 0; }
+    // toCheck must be non-zero
+    export function hasAll<F>(flags: BitFlags<F>, toCheck: BitFlags<F>) { return !!toCheck && ((flags as any) & (toCheck as any)) === (toCheck as any); }
 }
 
 export default BitFlags

+ 3 - 1
src/mol-data/model/properties/conformation.ts

@@ -11,13 +11,15 @@ interface Conformation {
     id: UUID,
 
     // ID is part of conformation because mmCIF is a leaky abstraction
-    // thats assigns different atom ids to corresponding atoms in different models
+    // that assigns different atom ids to corresponding atoms in different models
     // ... go figure.
     atomId: Column<number>,
 
     occupancy: Column<number>,
     B_iso_or_equiv: Column<number>
 
+    // Coordinates. Generally, not to be accessed directly because the coordinate might be
+    // transformed by an operator. Use Unit.getPosition instead.
     __x: ArrayLike<number>,
     __y: ArrayLike<number>,
     __z: ArrayLike<number>

+ 2 - 2
src/mol-data/structure.ts

@@ -12,12 +12,12 @@ import * as Base from './structure/base'
 //import Operator from './structure/operator'
 
 // TODO: do "single model" version of the structure?
-export interface Structure extends Readonly<{
+interface Structure extends Readonly<{
     units: { readonly [id: number]: Unit },
     atoms: AtomSet
 }> { }
 
-export namespace Structure {
+namespace Structure {
     export const Empty = Base.Empty;
     export const ofModel = Base.ofModel;
 

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

@@ -46,7 +46,7 @@ namespace AtomSet {
     // TODO: bounding sphere
     // TODO: distance, areWithIn?
     // TODO: check connected
-    // TODO: add "parent" property? how to avoid using too much memory? Transitive parents?
+    // TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
 }
 
 interface AtomSet { '@type': 'atom-set' }

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

@@ -4,3 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
+// TODO: bounding sphere
+// TODO: distance, areWithIn?
+// TODO: check connected
+// TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?

+ 13 - 0
src/mol-data/structure/atom.ts

@@ -5,6 +5,8 @@
  */
 
 import Tuple from '../../mol-base/collections/integer/tuple'
+import Unit from './unit'
+import Structure from '../structure'
 
 /** Atom pointer */
 interface Atom { '@type': Tuple['@type'] }
@@ -17,6 +19,17 @@ namespace Atom {
     export const index: (a: Atom) => number = Tuple.snd;
     export const areEqual: (a: Atom, b: Atom) => boolean = Tuple.areEqual;
     export const hashCode: (a: Atom) => number = Tuple.hashCode;
+
+    /** All the information required to access atom properties */
+    export interface Location { unit: Unit, atom: number }
+    export function Location(): Location { return { unit: {} as any, atom: 0 }; }
+    export interface Property<T> { (location: Location): T }
+    export interface Predicate extends Property<boolean> { }
+
+    export function setLocation(structure: Structure, l: Location, atom: Atom) {
+        l.unit = structure.units[unit(atom)];
+        l.atom = index(atom);
+    }
 }
 
 export default Atom

+ 2 - 2
src/mol-data/structure/base.ts

@@ -11,7 +11,7 @@ import Operator from './operator'
 import AtomSet from './atom-set'
 import OrderedSet from '../../mol-base/collections/integer/ordered-set'
 
-class Builder {
+export class StructureBuilder {
     private units = Object.create(null);
     private atoms = Object.create(null);
 
@@ -25,7 +25,7 @@ export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
 
 export function ofModel(model: Model): Structure {
     const chains = model.hierarchy.chainSegments;
-    const builder = new Builder();
+    const builder = new StructureBuilder();
 
     for (let c = 0; c < chains.count; c++) {
         const unit = Unit.create(model, Operator.Identity);

+ 0 - 69
src/mol-data/structure/property.ts

@@ -1,69 +0,0 @@
-/**
- * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import Structure from '../structure'
-import Atom from './atom'
-import Unit from './unit'
-import Model from '../model'
-import Column from '../../mol-base/collections/column'
-
-/** Atom pointer */
-interface Property<T> { (location: Property.Location): T }
-
-namespace Property {
-    export interface Predicate extends Property<boolean> { }
-
-    /** All the information required to access atom properties */
-    export interface Location {
-        //structure: Structure,
-        unit: Unit,
-        // hierarchy: Model['hierarchy'],
-        // conformation: Model['conformation'],
-        atomIndex: number,
-        // residueIndex: number,
-        // chainIndex: number
-    }
-
-    export function createLocation(): Location {
-        return {
-            //structure: structure!,
-            unit: {} as any,
-            //hierarchy: (!unit ? void 0 : unit.model.hierarchy)!,
-            //conformation: (!unit ? void 0 : unit.model.conformation)!,
-            atomIndex: 0
-            //residueIndex: 0,
-            //chainIndex: 0
-        };
-    }
-
-    export function update(l: Location, structure: Structure, atom: Atom) {
-        // const u = structure.units[Atom.unit(atom)];
-        // const i = Atom.index(atom);
-        // l.structure = structure;
-        // l.unit = u;
-        // l.atomIndex = i;
-        // l.residueIndex = u.residueIndex[i];
-        // l.chainIndex = u.chainIndex[i];
-        throw 'not implemented'
-    }
-
-    export function naive<T>(p: Property<T>) { return p; }
-
-    export function cachedAtomColumn<T>(col: (model: Model) => Column<T>): Property<T> {
-        let lastUnit: Unit | undefined = void 0;
-        let cached: ((row: number) => T) | undefined = void 0;
-        return function (location) {
-            if (location.unit === lastUnit && !!cached) return cached(location.atomIndex);
-            lastUnit = location.unit;
-            cached = col(lastUnit.model).value;
-            return cached(location.atomIndex);
-        };
-    }
-
-    // TODO: cached versions of other properties.
-}
-
-export default Property

+ 31 - 32
src/perf-tests/structure.ts

@@ -12,7 +12,6 @@ import CIF from '../mol-io/reader/cif'
 
 import buildModels from '../mol-data/model/builders/mmcif'
 import { ofModel } from '../mol-data/structure/base'
-import Property from '../mol-data/structure/property'
 import Model from '../mol-data/Model'
 import Structure from '../mol-data/structure'
 import OrdSet from '../mol-base/collections/integer/ordered-set'
@@ -80,10 +79,10 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumProperty(structure: Structure, p: Property<number>) {
+    function sumProperty(structure: Structure, p: Atom.Property<number>) {
         const { atoms, units } = structure;
         const unitIds = AtomSet.unitIds(atoms);
-        const l = Property.createLocation();
+        const l = Atom.Location();
 
         let s = 0;
 
@@ -92,7 +91,7 @@ export namespace PropertyAccess {
             const set = AtomSet.unitGetByIndex(atoms, i);
 
             for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
-                l.atomIndex = OrdSet.getAt(set, j);
+                l.atom = OrdSet.getAt(set, j);
                 s += p(l);
             }
         }
@@ -100,10 +99,10 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumPropertySegmented(structure: Structure, p: Property<number>) {
+    function sumPropertySegmented(structure: Structure, p: Atom.Property<number>) {
         const { atoms, units } = structure;
         const unitIds = AtomSet.unitIds(atoms);
-        const l = Property.createLocation();
+        const l = Atom.Location();
 
         let s = 0;
 
@@ -120,7 +119,7 @@ export namespace PropertyAccess {
                 while (residuesIt.hasNext) {
                     const residueSegment = residuesIt.move();
                     for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
-                        l.atomIndex = OrdSet.getAt(set, j);
+                        l.atom = OrdSet.getAt(set, j);
                         s += p(l);
                     }
                 }
@@ -130,10 +129,10 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumPropertyResidue(structure: Structure, p: Property<number>) {
+    function sumPropertyResidue(structure: Structure, p: Atom.Property<number>) {
         const { atoms, units } = structure;
         const unitIds = AtomSet.unitIds(atoms);
-        const l = Property.createLocation();
+        const l = Atom.Location();
 
         let s = 0;
 
@@ -143,7 +142,7 @@ export namespace PropertyAccess {
             const set = AtomSet.unitGetByIndex(atoms, i);
             const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);
             while (residuesIt.hasNext) {
-                l.atomIndex = OrdSet.getAt(set, residuesIt.move().start);
+                l.atom = OrdSet.getAt(set, residuesIt.move().start);
                 s += p(l);
             }
         }
@@ -151,16 +150,16 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumPropertyAtomSetIt(structure: Structure, p: Property<number>) {
+    function sumPropertyAtomSetIt(structure: Structure, p: Atom.Property<number>) {
         const { atoms, units } = structure;
 
         let s = 0;
         const atomsIt = AtomSet.atoms(atoms);
-        const l = Property.createLocation();
+        const l = Atom.Location();
         while (atomsIt.hasNext) {
             const a = atomsIt.move();
             l.unit = units[Atom.unit(a)];
-            l.atomIndex = Atom.index(a);
+            l.atom = Atom.index(a);
             s += p(l);
         }
         return s;
@@ -186,7 +185,7 @@ export namespace PropertyAccess {
     //             while (residuesIt.hasNext) {
     //                 const residueSegment = residuesIt.move();
     //                 for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
-    //                     l.atomIndex = OrdSet.getAt(set, j);
+    //                     l.atom = OrdSet.getAt(set, j);
     //                     s += p(l);
     //                 }
     //             }
@@ -232,7 +231,7 @@ export namespace PropertyAccess {
 
     //         for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
     //             const aI = OrdSet.getAt(set, j);
-    //             l.atomIndex = aI;
+    //             l.atom = aI;
     //             l.residueIndex = residueIndex[aI];
     //             l.chainIndex = chainIndex[aI];
     //             s[s.length] = p(l);
@@ -251,33 +250,33 @@ export namespace PropertyAccess {
 
         console.log(baseline(models[0]));
         console.log(baselineRaw(models[0]));
-        console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
-        console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
-        //console.log(sumPropertySegmentedMutable(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
-        console.log(sumPropertyAtomSetIt(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)));
-        console.log(sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)));
+        console.log(sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
+        console.log(sumPropertySegmented(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
+        //console.log(sumPropertySegmentedMutable(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
+        console.log(sumPropertyAtomSetIt(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)));
+        //console.log(sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)));
         console.log(sumDirect(structures[0]));
-        console.log('r', sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atomIndex])));
+        console.log('r', sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])));
 
         //const col = models[0].conformation.atomId.value;
         const suite = new B.Suite();
         suite
-            //.add('test int', () => sumProperty(structures[0], l => col(l.atomIndex)))
+            //.add('test int', () => sumProperty(structures[0], l => col(l.atom)))
             // .add('baseline raw', () =>  baselineRaw(models[0]))
-            .add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atomIndex])))
+            .add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])))
 
             .add('baseline', () =>  baseline(models[0]))
             .add('direct', () =>  sumDirect(structures[0]))
-            //.add('normal int', () => sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atomIndex)))
-            //.add('atom set it int', () => sumPropertyAtomSetIt(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
-            // .add('segmented faster int', () => sumPropertySegmented(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
-            // .add('faster int', () => sumProperty(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
-            .add('segmented faster _x', () => sumPropertySegmented(structures[0], l => l.unit.conformation.__x[l.atomIndex]))
-            .add('faster _x', () => sumProperty(structures[0], l => l.unit.conformation.__x[l.atomIndex] +  l.unit.conformation.__y[l.atomIndex] +  l.unit.conformation.__z[l.atomIndex]))
-            //.add('segmented mut faster int', () => sumPropertySegmentedMutable(structures[0], l => l.unit.conformation.atomId.value(l.atomIndex)))
-            //.add('normal shortcut int', () => sumProperty(structures[0], l => l.conformation.atomId.value(l.atomIndex)))
+            //.add('normal int', () => sumProperty(structures[0], l => l.unit.model.conformation.atomId.value(l.atom)))
+            //.add('atom set it int', () => sumPropertyAtomSetIt(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
+            // .add('segmented faster int', () => sumPropertySegmented(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
+            // .add('faster int', () => sumProperty(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
+            .add('segmented faster _x', () => sumPropertySegmented(structures[0], l => l.unit.conformation.__x[l.atom]))
+            .add('faster _x', () => sumProperty(structures[0], l => l.unit.conformation.__x[l.atom] +  l.unit.conformation.__y[l.atom] +  l.unit.conformation.__z[l.atom]))
+            //.add('segmented mut faster int', () => sumPropertySegmentedMutable(structures[0], l => l.unit.conformation.atomId.value(l.atom)))
+            //.add('normal shortcut int', () => sumProperty(structures[0], l => l.conformation.atomId.value(l.atom)))
             //.add('cached int', () => sumProperty(structures[0], Property.cachedAtomColumn(m => m.conformation.atomId)))
-            //.add('concat str', () => concatProperty(structures[0], l => l.unit.model.hierarchy.atoms.auth_atom_id.value(l.atomIndex)))
+            //.add('concat str', () => concatProperty(structures[0], l => l.unit.model.hierarchy.atoms.auth_atom_id.value(l.atom)))
             //.add('cached concat str', () => concatProperty(structures[0], Property.cachedAtomColumn(m => m.hierarchy.atoms.auth_atom_id)))
             .on('cycle', (e: any) => console.log(String(e.target)))
             .run();