Bladeren bron

Renamed Atom* to Element*

David Sehnal 7 jaren geleden
bovenliggende
commit
606dde2366

+ 116 - 116
src/mol-model/structure/_spec/atom-set.spec.ts

@@ -5,16 +5,16 @@
  */
 
 import { OrderedSet } from 'mol-data/int'
-import AtomSet from '../structure/atom/set'
-import Atom from '../structure/atom'
-import AtomGroup from '../structure/atom/group'
+import ElementSet from '../structure/element/set'
+import Element from '../structure/element'
+import ElementGroup from '../structure/element/group'
 
 describe('atom set', () => {
-    const p = (i: number, j: number) => Atom.create(i, j);
+    const p = (i: number, j: number) => Element.create(i, j);
 
-    function setToPairs(set: AtomSet): ArrayLike<Atom> {
-        const ret: Atom[] = [];
-        const it = AtomSet.atoms(set);
+    function setToPairs(set: ElementSet): ArrayLike<Element> {
+        const ret: Element[] = [];
+        const it = ElementSet.elements(set);
         while (it.hasNext) {
             ret[ret.length] = it.move();
         }
@@ -22,181 +22,181 @@ describe('atom set', () => {
     }
 
     it('singleton pair', () => {
-        const set = AtomSet.ofAtoms([p(10, 11)], AtomSet.Empty);
+        const set = ElementSet.ofAtoms([p(10, 11)], ElementSet.Empty);
         expect(setToPairs(set)).toEqual([p(10, 11)]);
-        expect(AtomSet.atomHas(set, p(10, 11))).toBe(true);
-        expect(AtomSet.atomHas(set, p(11, 11))).toBe(false);
-        expect(AtomSet.atomGetAt(set, 0)).toBe(p(10, 11));
-        expect(AtomSet.atomCount(set)).toBe(1);
+        expect(ElementSet.elementHas(set, p(10, 11))).toBe(true);
+        expect(ElementSet.elementHas(set, p(11, 11))).toBe(false);
+        expect(ElementSet.elementGetAt(set, 0)).toBe(p(10, 11));
+        expect(ElementSet.elementCount(set)).toBe(1);
     });
 
     it('singleton atom', () => {
-        const set = AtomSet.singleton(p(10, 11), AtomSet.Empty);
+        const set = ElementSet.singleton(p(10, 11), ElementSet.Empty);
         expect(setToPairs(set)).toEqual([p(10, 11)]);
-        expect(AtomSet.atomHas(set, p(10, 11))).toBe(true);
-        expect(AtomSet.atomHas(set, p(11, 11))).toBe(false);
-        expect(AtomSet.atomGetAt(set, 0)).toBe(p(10, 11));
-        expect(AtomSet.atomCount(set)).toBe(1);
+        expect(ElementSet.elementHas(set, p(10, 11))).toBe(true);
+        expect(ElementSet.elementHas(set, p(11, 11))).toBe(false);
+        expect(ElementSet.elementGetAt(set, 0)).toBe(p(10, 11));
+        expect(ElementSet.elementCount(set)).toBe(1);
     });
 
     it('multi', () => {
-        const gen = AtomSet.Generator();
-        gen.add(1, AtomGroup.createNew(OrderedSet.ofSortedArray([4, 6, 7])));
-        gen.add(3, AtomGroup.createNew(OrderedSet.ofRange(0, 1)));
+        const gen = ElementSet.Generator();
+        gen.add(1, ElementGroup.createNew(OrderedSet.ofSortedArray([4, 6, 7])));
+        gen.add(3, ElementGroup.createNew(OrderedSet.ofRange(0, 1)));
         const set = gen.getSet();
         const ret = [p(1, 4), p(1, 6), p(1, 7), p(3, 0), p(3, 1)];
-        expect(AtomSet.atomCount(set)).toBe(ret.length);
+        expect(ElementSet.elementCount(set)).toBe(ret.length);
         expect(setToPairs(set)).toEqual([p(1, 4), p(1, 6), p(1, 7), p(3, 0), p(3, 1)]);
-        expect(AtomSet.atomHas(set, p(10, 11))).toBe(false);
-        expect(AtomSet.atomHas(set, p(3, 0))).toBe(true);
-        expect(AtomSet.atomHas(set, p(1, 7))).toBe(true);
-        for (let i = 0; i < AtomSet.atomCount(set); i++) {
-            expect(Atom.areEqual(AtomSet.atomGetAt(set, i), ret[i])).toBe(true);
+        expect(ElementSet.elementHas(set, p(10, 11))).toBe(false);
+        expect(ElementSet.elementHas(set, p(3, 0))).toBe(true);
+        expect(ElementSet.elementHas(set, p(1, 7))).toBe(true);
+        for (let i = 0; i < ElementSet.elementCount(set); i++) {
+            expect(Element.areEqual(ElementSet.elementGetAt(set, i), ret[i])).toBe(true);
         }
     });
 
     it('template', () => {
-        const template = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty)
-        const gen = AtomSet.TemplateGenerator(template);
+        const template = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty)
+        const gen = ElementSet.TemplateGenerator(template);
         gen.add(0, OrderedSet.ofSortedArray([1, 2, 6]));
         gen.add(1, OrderedSet.ofSingleton(3));
         const set = gen.getSet();
 
-        expect(AtomSet.unitGetById(set, 0)).toBe(AtomSet.unitGetById(template, 0));
-        expect(AtomSet.unitGetById(set, 1)).toBe(AtomSet.unitGetById(template, 1));
+        expect(ElementSet.unitGetById(set, 0)).toBe(ElementSet.unitGetById(template, 0));
+        expect(ElementSet.unitGetById(set, 1)).toBe(ElementSet.unitGetById(template, 1));
         expect(set).toBe(template);
     });
 
     it('template 1', () => {
-        const template = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty)
-        const gen = AtomSet.TemplateGenerator(template);
+        const template = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty)
+        const gen = ElementSet.TemplateGenerator(template);
         gen.add(0, OrderedSet.ofSortedArray([1, 2, 6]));
         gen.add(1, OrderedSet.ofSingleton(4));
         const set = gen.getSet();
 
-        expect(AtomSet.unitGetById(set, 0)).toBe(AtomSet.unitGetById(template, 0));
-        expect(AtomSet.unitGetById(set, 1) === AtomSet.unitGetById(template, 1)).toBe(false);
+        expect(ElementSet.unitGetById(set, 0)).toBe(ElementSet.unitGetById(template, 0));
+        expect(ElementSet.unitGetById(set, 1) === ElementSet.unitGetById(template, 1)).toBe(false);
         expect(set === template).toBe(false);
     });
 
     it('template union', () => {
-        const template = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty)
-
-        const p13 = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const p01 = AtomSet.ofAtoms([p(0, 1)], AtomSet.Empty);
-        const p02 = AtomSet.ofAtoms([p(0, 2)], AtomSet.Empty);
-        const p06 = AtomSet.ofAtoms([p(0, 6)], AtomSet.Empty);
-
-        const u0 = AtomSet.union([p01, p02, p06], template);
-        const u1 = AtomSet.union([p01, p02, p06, p13], template);
-        expect(AtomSet.unitGetById(u0, 0)).toBe(AtomSet.unitGetById(template, 0));
-        expect(AtomSet.unitGetById(u1, 0)).toBe(AtomSet.unitGetById(template, 0));
-        expect(AtomSet.unitGetById(u1, 1)).toBe(AtomSet.unitGetById(template, 1));
+        const template = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty)
+
+        const p13 = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const p01 = ElementSet.ofAtoms([p(0, 1)], ElementSet.Empty);
+        const p02 = ElementSet.ofAtoms([p(0, 2)], ElementSet.Empty);
+        const p06 = ElementSet.ofAtoms([p(0, 6)], ElementSet.Empty);
+
+        const u0 = ElementSet.union([p01, p02, p06], template);
+        const u1 = ElementSet.union([p01, p02, p06, p13], template);
+        expect(ElementSet.unitGetById(u0, 0)).toBe(ElementSet.unitGetById(template, 0));
+        expect(ElementSet.unitGetById(u1, 0)).toBe(ElementSet.unitGetById(template, 0));
+        expect(ElementSet.unitGetById(u1, 1)).toBe(ElementSet.unitGetById(template, 1));
         expect(u1).toBe(template);
     });
 
     it('element at / index of', () => {
-        const control: Atom[] = [];
-        const gen = AtomSet.Generator();
+        const control: Element[] = [];
+        const gen = ElementSet.Generator();
         for (let i = 1; i < 10; i++) {
             const set = [];
             for (let j = 1; j < 7; j++) {
                 control[control.length] = p(i * i, j * j + 1);
                 set[set.length] = j * j + 1;
             }
-            gen.add(i * i, AtomGroup.createNew(OrderedSet.ofSortedArray(set)));
+            gen.add(i * i, ElementGroup.createNew(OrderedSet.ofSortedArray(set)));
         }
         const ms = gen.getSet();
         for (let i = 0; i < control.length; i++) {
-            expect(Atom.areEqual(AtomSet.atomGetAt(ms, i), control[i])).toBe(true);
+            expect(Element.areEqual(ElementSet.elementGetAt(ms, i), control[i])).toBe(true);
         }
 
         for (let i = 0; i < control.length; i++) {
-            expect(AtomSet.atomIndexOf(ms, control[i])).toBe(i);
+            expect(ElementSet.elementIndexOf(ms, control[i])).toBe(i);
         }
     });
 
     it('packed pairs', () => {
-        const set = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
+        const set = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
         expect(setToPairs(set)).toEqual([p(0, 1), p(0, 2), p(0, 6), p(1, 3)]);
     });
 
     it('equality', () => {
-        const a = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const b = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const c = AtomSet.ofAtoms([p(1, 3), p(0, 4), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const d = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const e = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const f = AtomSet.ofAtoms([p(3, 3)], AtomSet.Empty);
-
-        expect(AtomSet.areEqual(a, a)).toBe(true);
-        expect(AtomSet.areEqual(a, b)).toBe(true);
-        expect(AtomSet.areEqual(a, c)).toBe(false);
-        expect(AtomSet.areEqual(a, d)).toBe(false);
-        expect(AtomSet.areEqual(d, d)).toBe(true);
-        expect(AtomSet.areEqual(d, e)).toBe(true);
-        expect(AtomSet.areEqual(d, f)).toBe(false);
+        const a = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const b = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const c = ElementSet.ofAtoms([p(1, 3), p(0, 4), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const d = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const e = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const f = ElementSet.ofAtoms([p(3, 3)], ElementSet.Empty);
+
+        expect(ElementSet.areEqual(a, a)).toBe(true);
+        expect(ElementSet.areEqual(a, b)).toBe(true);
+        expect(ElementSet.areEqual(a, c)).toBe(false);
+        expect(ElementSet.areEqual(a, d)).toBe(false);
+        expect(ElementSet.areEqual(d, d)).toBe(true);
+        expect(ElementSet.areEqual(d, e)).toBe(true);
+        expect(ElementSet.areEqual(d, f)).toBe(false);
     });
 
     it('are intersecting', () => {
-        const a = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const b = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const c = AtomSet.ofAtoms([p(1, 3), p(0, 4), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const d = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const e = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const f = AtomSet.ofAtoms([p(3, 3)], AtomSet.Empty);
-        const g = AtomSet.ofAtoms([p(10, 3), p(8, 1), p(7, 6), p(3, 2)], AtomSet.Empty);
-
-        expect(AtomSet.areIntersecting(a, a)).toBe(true);
-        expect(AtomSet.areIntersecting(a, b)).toBe(true);
-        expect(AtomSet.areIntersecting(a, c)).toBe(true);
-        expect(AtomSet.areIntersecting(a, d)).toBe(true);
-        expect(AtomSet.areIntersecting(a, g)).toBe(false);
-        expect(AtomSet.areIntersecting(d, d)).toBe(true);
-        expect(AtomSet.areIntersecting(d, e)).toBe(true);
-        expect(AtomSet.areIntersecting(d, f)).toBe(false);
+        const a = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const b = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const c = ElementSet.ofAtoms([p(1, 3), p(0, 4), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const d = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const e = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const f = ElementSet.ofAtoms([p(3, 3)], ElementSet.Empty);
+        const g = ElementSet.ofAtoms([p(10, 3), p(8, 1), p(7, 6), p(3, 2)], ElementSet.Empty);
+
+        expect(ElementSet.areIntersecting(a, a)).toBe(true);
+        expect(ElementSet.areIntersecting(a, b)).toBe(true);
+        expect(ElementSet.areIntersecting(a, c)).toBe(true);
+        expect(ElementSet.areIntersecting(a, d)).toBe(true);
+        expect(ElementSet.areIntersecting(a, g)).toBe(false);
+        expect(ElementSet.areIntersecting(d, d)).toBe(true);
+        expect(ElementSet.areIntersecting(d, e)).toBe(true);
+        expect(ElementSet.areIntersecting(d, f)).toBe(false);
     });
 
     it('intersection', () => {
-        const a = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const b = AtomSet.ofAtoms([p(10, 3), p(0, 1), p(0, 6), p(4, 2)], AtomSet.Empty);
-        const c = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const d = AtomSet.ofAtoms([p(2, 3)], AtomSet.Empty);
-        expect(AtomSet.intersect(a, a)).toBe(a);
-        expect(setToPairs(AtomSet.intersect(a, b))).toEqual([p(0, 1), p(0, 6)]);
-        expect(setToPairs(AtomSet.intersect(a, c))).toEqual([p(1, 3)]);
-        expect(setToPairs(AtomSet.intersect(c, d))).toEqual([]);
+        const a = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const b = ElementSet.ofAtoms([p(10, 3), p(0, 1), p(0, 6), p(4, 2)], ElementSet.Empty);
+        const c = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const d = ElementSet.ofAtoms([p(2, 3)], ElementSet.Empty);
+        expect(ElementSet.intersect(a, a)).toBe(a);
+        expect(setToPairs(ElementSet.intersect(a, b))).toEqual([p(0, 1), p(0, 6)]);
+        expect(setToPairs(ElementSet.intersect(a, c))).toEqual([p(1, 3)]);
+        expect(setToPairs(ElementSet.intersect(c, d))).toEqual([]);
     });
 
     it('subtract', () => {
-        const a = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const a1 = AtomSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], AtomSet.Empty);
-        const b = AtomSet.ofAtoms([p(10, 3), p(0, 1), p(0, 6), p(4, 2)], AtomSet.Empty);
-        const c = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const d = AtomSet.ofAtoms([p(2, 3)], AtomSet.Empty);
-        const e = AtomSet.ofAtoms([p(0, 2)], AtomSet.Empty);
-        expect(setToPairs(AtomSet.subtract(a, a))).toEqual([]);
-        expect(setToPairs(AtomSet.subtract(a, a1))).toEqual([]);
-        expect(setToPairs(AtomSet.subtract(a, b))).toEqual([p(0, 2), p(1, 3)]);
-        expect(setToPairs(AtomSet.subtract(c, d))).toEqual([p(1, 3)]);
-        expect(setToPairs(AtomSet.subtract(a, c))).toEqual([p(0, 1), p(0, 2), p(0, 6)]);
-        expect(setToPairs(AtomSet.subtract(c, a))).toEqual([]);
-        expect(setToPairs(AtomSet.subtract(d, a))).toEqual([p(2, 3)]);
-        expect(setToPairs(AtomSet.subtract(a, e))).toEqual([p(0, 1), p(0, 6), p(1, 3)]);
+        const a = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const a1 = ElementSet.ofAtoms([p(1, 3), p(0, 1), p(0, 6), p(0, 2)], ElementSet.Empty);
+        const b = ElementSet.ofAtoms([p(10, 3), p(0, 1), p(0, 6), p(4, 2)], ElementSet.Empty);
+        const c = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const d = ElementSet.ofAtoms([p(2, 3)], ElementSet.Empty);
+        const e = ElementSet.ofAtoms([p(0, 2)], ElementSet.Empty);
+        expect(setToPairs(ElementSet.subtract(a, a))).toEqual([]);
+        expect(setToPairs(ElementSet.subtract(a, a1))).toEqual([]);
+        expect(setToPairs(ElementSet.subtract(a, b))).toEqual([p(0, 2), p(1, 3)]);
+        expect(setToPairs(ElementSet.subtract(c, d))).toEqual([p(1, 3)]);
+        expect(setToPairs(ElementSet.subtract(a, c))).toEqual([p(0, 1), p(0, 2), p(0, 6)]);
+        expect(setToPairs(ElementSet.subtract(c, a))).toEqual([]);
+        expect(setToPairs(ElementSet.subtract(d, a))).toEqual([p(2, 3)]);
+        expect(setToPairs(ElementSet.subtract(a, e))).toEqual([p(0, 1), p(0, 6), p(1, 3)]);
     });
 
     it('union', () => {
-        const a = AtomSet.ofAtoms([p(1, 3), p(0, 1)], AtomSet.Empty);
-        const a1 = AtomSet.ofAtoms([p(1, 3), p(0, 1)], AtomSet.Empty);
-        const b = AtomSet.ofAtoms([p(10, 3), p(0, 1)], AtomSet.Empty);
-        const c = AtomSet.ofAtoms([p(1, 3)], AtomSet.Empty);
-        const d = AtomSet.ofAtoms([p(2, 3)], AtomSet.Empty);
-        expect(AtomSet.union([a], AtomSet.Empty)).toBe(a);
-        expect(AtomSet.union([a, a], AtomSet.Empty)).toBe(a);
-        expect(setToPairs(AtomSet.union([a, a], AtomSet.Empty))).toEqual([p(0, 1), p(1, 3)]);
-        expect(setToPairs(AtomSet.union([a, a1], AtomSet.Empty))).toEqual([p(0, 1), p(1, 3)]);
-        expect(setToPairs(AtomSet.union([a, b], AtomSet.Empty))).toEqual([p(0, 1), p(1, 3), p(10, 3)]);
-        expect(setToPairs(AtomSet.union([c, d], AtomSet.Empty))).toEqual([p(1, 3), p(2, 3)]);
-        expect(setToPairs(AtomSet.union([a, b, c, d], AtomSet.Empty))).toEqual([p(0, 1), p(1, 3), p(2, 3), p(10, 3)]);
+        const a = ElementSet.ofAtoms([p(1, 3), p(0, 1)], ElementSet.Empty);
+        const a1 = ElementSet.ofAtoms([p(1, 3), p(0, 1)], ElementSet.Empty);
+        const b = ElementSet.ofAtoms([p(10, 3), p(0, 1)], ElementSet.Empty);
+        const c = ElementSet.ofAtoms([p(1, 3)], ElementSet.Empty);
+        const d = ElementSet.ofAtoms([p(2, 3)], ElementSet.Empty);
+        expect(ElementSet.union([a], ElementSet.Empty)).toBe(a);
+        expect(ElementSet.union([a, a], ElementSet.Empty)).toBe(a);
+        expect(setToPairs(ElementSet.union([a, a], ElementSet.Empty))).toEqual([p(0, 1), p(1, 3)]);
+        expect(setToPairs(ElementSet.union([a, a1], ElementSet.Empty))).toEqual([p(0, 1), p(1, 3)]);
+        expect(setToPairs(ElementSet.union([a, b], ElementSet.Empty))).toEqual([p(0, 1), p(1, 3), p(10, 3)]);
+        expect(setToPairs(ElementSet.union([c, d], ElementSet.Empty))).toEqual([p(1, 3), p(2, 3)]);
+        expect(setToPairs(ElementSet.union([a, b, c, d], ElementSet.Empty))).toEqual([p(0, 1), p(1, 3), p(2, 3), p(10, 3)]);
     });
 });

+ 4 - 4
src/mol-model/structure/export/mmcif.ts

@@ -9,7 +9,7 @@ import { Column } from 'mol-data/db'
 import Iterator from 'mol-data/iterator'
 import * as Encoder from 'mol-io/writer/cif'
 // import { mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif'
-import { Structure, Atom, AtomSet } from '../structure'
+import { Structure, Element, ElementSet } from '../structure'
 import { Model } from '../model'
 import P from '../query/properties'
 
@@ -68,7 +68,7 @@ function float<K, D = any>(name: string, value: (k: K, d: D) => number, valueKin
 //     //...
 // }
 
-const atom_site: Encoder.CategoryDefinition<Atom.Location> = {
+const atom_site: Encoder.CategoryDefinition<Element.Location> = {
     name: 'atom_site',
     fields: [
         str('group_PDB', P.residue.group_PDB),
@@ -113,8 +113,8 @@ function atomSiteProvider({ structure }: Context): Encoder.CategoryInstance {
     return {
         data: void 0,
         definition: atom_site,
-        keys: () => Structure.atomLocationsTransient(structure),
-        rowCount: AtomSet.atomCount(structure.atoms)
+        keys: () => Structure.elementLocationsTransient(structure),
+        rowCount: ElementSet.elementCount(structure.elements)
     }
 }
 

+ 30 - 30
src/mol-model/structure/query/generators.ts

@@ -7,21 +7,21 @@
 import Query from './query'
 import Selection from './selection'
 import P from './properties'
-import { Structure, AtomSet, Atom } from '../structure'
+import { Structure, ElementSet, Element } from '../structure'
 import { OrderedSet, Segmentation } from 'mol-data/int'
 
-export const all: Query = s => Selection.Singletons(s, s.atoms);
+export const all: Query = s => Selection.Singletons(s, s.elements);
 
 export interface AtomQueryParams {
-    entityTest: Atom.Predicate,
-    chainTest: Atom.Predicate,
-    residueTest: Atom.Predicate,
-    atomTest: Atom.Predicate,
-    groupBy: Atom.Property<any>
+    entityTest: Element.Predicate,
+    chainTest: Element.Predicate,
+    residueTest: Element.Predicate,
+    atomTest: Element.Predicate,
+    groupBy: Element.Property<any>
 }
 
 export interface AtomGroupsQueryParams extends AtomQueryParams {
-    groupBy: Atom.Property<any>
+    groupBy: Element.Property<any>
 }
 
 export function residues(params?: Partial<AtomQueryParams>) { return atoms({ ...params, groupBy: P.residue.key }); }
@@ -43,17 +43,17 @@ export function atoms(params?: Partial<AtomGroupsQueryParams>): Query {
     return atomGroupsGrouped(normalized);
 }
 
-function atomGroupsLinear(atomTest: Atom.Predicate): Query {
+function atomGroupsLinear(atomTest: Element.Predicate): Query {
     return structure => {
-        const { atoms, units } = structure;
-        const unitIds = AtomSet.unitIds(atoms);
-        const l = Atom.Location();
-        const builder = AtomSet.LinearBuilder(atoms);
+        const { elements, units } = structure;
+        const unitIds = ElementSet.unitIds(elements);
+        const l = Element.Location();
+        const builder = ElementSet.LinearBuilder(elements);
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unitId = unitIds[i];
             l.unit = units[unitId];
-            const set = AtomSet.unitGetByIndex(atoms, i).atoms;
+            const set = ElementSet.unitGetByIndex(elements, i).elements;
 
             builder.beginUnit();
             for (let j = 0, _j = OrderedSet.size(set); j < _j; j++) {
@@ -69,16 +69,16 @@ function atomGroupsLinear(atomTest: Atom.Predicate): Query {
 
 function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomGroupsQueryParams): Query {
     return structure => {
-        const { atoms, units } = structure;
-        const unitIds = AtomSet.unitIds(atoms);
-        const l = Atom.Location();
-        const builder = AtomSet.LinearBuilder(atoms);
+        const { elements, units } = structure;
+        const unitIds = ElementSet.unitIds(elements);
+        const l = Element.Location();
+        const builder = ElementSet.LinearBuilder(elements);
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unitId = unitIds[i];
             const unit = units[unitId];
             l.unit = unit;
-            const set = AtomSet.unitGetByIndex(atoms, i).atoms;
+            const set = ElementSet.unitGetByIndex(elements, i).elements;
 
             builder.beginUnit();
             const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
@@ -111,13 +111,13 @@ function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: A
 }
 
 class LinearGroupingBuilder {
-    private builders: AtomSet.Builder[] = [];
-    private builderMap = new Map<string, AtomSet.Builder>();
+    private builders: ElementSet.Builder[] = [];
+    private builderMap = new Map<string, ElementSet.Builder>();
 
     add(key: any, unit: number, atom: number) {
         let b = this.builderMap.get(key);
         if (!b) {
-            b = AtomSet.LinearBuilder(this.structure.atoms);
+            b = ElementSet.LinearBuilder(this.structure.elements);
             this.builders[this.builders.length] = b;
             this.builderMap.set(key, b);
         }
@@ -126,21 +126,21 @@ class LinearGroupingBuilder {
 
     private allSingletons() {
         for (let i = 0, _i = this.builders.length; i < _i; i++) {
-            if (this.builders[i].atomCount > 1) return false;
+            if (this.builders[i].elementCount > 1) return false;
         }
         return true;
     }
 
     private singletonSelection(): Selection {
-        const atoms: Atom[] = Atom.createEmptyArray(this.builders.length);
+        const atoms: Element[] = Element.createEmptyArray(this.builders.length);
         for (let i = 0, _i = this.builders.length; i < _i; i++) {
             atoms[i] = this.builders[i].singleton();
         }
-        return Selection.Singletons(this.structure, AtomSet.ofAtoms(atoms, this.structure.atoms));
+        return Selection.Singletons(this.structure, ElementSet.ofAtoms(atoms, this.structure.elements));
     }
 
     private fullSelection() {
-        const sets: AtomSet[] = new Array(this.builders.length);
+        const sets: ElementSet[] = new Array(this.builders.length);
         for (let i = 0, _i = this.builders.length; i < _i; i++) {
             sets[i] = this.builders[i].getSet();
         }
@@ -159,16 +159,16 @@ class LinearGroupingBuilder {
 
 function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomGroupsQueryParams): Query {
     return structure => {
-        const { atoms, units } = structure;
-        const unitIds = AtomSet.unitIds(atoms);
-        const l = Atom.Location();
+        const { elements, units } = structure;
+        const unitIds = ElementSet.unitIds(elements);
+        const l = Element.Location();
         const builder = new LinearGroupingBuilder(structure);
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unitId = unitIds[i];
             const unit = units[unitId];
             l.unit = unit;
-            const set = AtomSet.unitGetByIndex(atoms, i).atoms;
+            const set = ElementSet.unitGetByIndex(elements, i).elements;
 
             const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
             const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);

+ 9 - 9
src/mol-model/structure/query/predicates.ts

@@ -4,20 +4,20 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Atom } from '../structure'
+import { Element } from '../structure'
 import P from './properties'
 
 namespace Predicates {
     export interface SetLike<A> { has(v: A): boolean }
     function isSetLike<A>(x: any): x is SetLike<A> { return !!x && !!x.has }
 
-    export function eq<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) === value; }
-    export function lt<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) < value; }
-    export function lte<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) <= value; }
-    export function gt<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) > value; }
-    export function gte<A>(p: Atom.Property<A>, value: A): Atom.Predicate { return l => p(l) >= value; }
+    export function eq<A>(p: Element.Property<A>, value: A): Element.Predicate { return l => p(l) === value; }
+    export function lt<A>(p: Element.Property<A>, value: A): Element.Predicate { return l => p(l) < value; }
+    export function lte<A>(p: Element.Property<A>, value: A): Element.Predicate { return l => p(l) <= value; }
+    export function gt<A>(p: Element.Property<A>, value: A): Element.Predicate { return l => p(l) > value; }
+    export function gte<A>(p: Element.Property<A>, value: A): Element.Predicate { return l => p(l) >= value; }
 
-    export function inSet<A>(p: Atom.Property<A>, values: SetLike<A> | ArrayLike<A>): Atom.Predicate {
+    export function inSet<A>(p: Element.Property<A>, values: SetLike<A> | ArrayLike<A>): Element.Predicate {
         if (isSetLike(values)) {
             return l => values.has(p(l));
         } else {
@@ -28,7 +28,7 @@ namespace Predicates {
         }
     }
 
-    export function and(...ps: Atom.Predicate[]): Atom.Predicate {
+    export function and(...ps: Element.Predicate[]): Element.Predicate {
         switch (ps.length) {
             case 0: return P.constant.true;
             case 1: return ps[0];
@@ -62,7 +62,7 @@ namespace Predicates {
         }
     }
 
-    export function or(...ps: Atom.Predicate[]): Atom.Predicate {
+    export function or(...ps: Element.Predicate[]): Element.Predicate {
         switch (ps.length) {
             case 0: return P.constant.false;
             case 1: return ps[0];

+ 41 - 41
src/mol-model/structure/query/properties.ts

@@ -4,12 +4,12 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Atom, Unit } from '../structure'
+import { Element, Unit } from '../structure'
 
 const constant = {
-    true: Atom.property(l => true),
-    false: Atom.property(l => false),
-    zero: Atom.property(l => 0)
+    true: Element.property(l => true),
+    false: Element.property(l => false),
+    zero: Element.property(l => 0)
 }
 
 function notAtomic(): never {
@@ -17,63 +17,63 @@ function notAtomic(): never {
 }
 
 const atom = {
-    key: Atom.property(l => l.atom),
+    key: Element.property(l => l.atom),
 
     // Conformation
-    x: Atom.property(l => l.unit.x(l.atom)),
-    y: Atom.property(l => l.unit.y(l.atom)),
-    z: Atom.property(l => l.unit.z(l.atom)),
-    id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.atomId.value(l.atom)),
-    occupancy: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.occupancy.value(l.atom)),
-    B_iso_or_equiv: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.B_iso_or_equiv.value(l.atom)),
+    x: Element.property(l => l.unit.x(l.atom)),
+    y: Element.property(l => l.unit.y(l.atom)),
+    z: Element.property(l => l.unit.z(l.atom)),
+    id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.atomId.value(l.atom)),
+    occupancy: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.occupancy.value(l.atom)),
+    B_iso_or_equiv: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.conformation.B_iso_or_equiv.value(l.atom)),
 
     // Hierarchy
-    type_symbol: Atom.property(l => l.unit.hierarchy.atoms.type_symbol.value(l.atom)),
-    label_atom_id: Atom.property(l => l.unit.hierarchy.atoms.label_atom_id.value(l.atom)),
-    auth_atom_id: Atom.property(l => l.unit.hierarchy.atoms.auth_atom_id.value(l.atom)),
-    label_alt_id: Atom.property(l => l.unit.hierarchy.atoms.label_alt_id.value(l.atom)),
-    pdbx_formal_charge: Atom.property(l => l.unit.hierarchy.atoms.pdbx_formal_charge.value(l.atom))
+    type_symbol: Element.property(l => l.unit.hierarchy.atoms.type_symbol.value(l.atom)),
+    label_atom_id: Element.property(l => l.unit.hierarchy.atoms.label_atom_id.value(l.atom)),
+    auth_atom_id: Element.property(l => l.unit.hierarchy.atoms.auth_atom_id.value(l.atom)),
+    label_alt_id: Element.property(l => l.unit.hierarchy.atoms.label_alt_id.value(l.atom)),
+    pdbx_formal_charge: Element.property(l => l.unit.hierarchy.atoms.pdbx_formal_charge.value(l.atom))
 }
 
 const residue = {
-    key: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residueKey.value(l.unit.residueIndex[l.atom])),
-
-    group_PDB: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.group_PDB.value(l.unit.residueIndex[l.atom])),
-    label_comp_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.label_comp_id.value(l.unit.residueIndex[l.atom])),
-    auth_comp_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.auth_comp_id.value(l.unit.residueIndex[l.atom])),
-    label_seq_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.label_seq_id.value(l.unit.residueIndex[l.atom])),
-    auth_seq_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])),
-    pdbx_PDB_ins_code: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.pdbx_PDB_ins_code.value(l.unit.residueIndex[l.atom]))
+    key: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residueKey.value(l.unit.residueIndex[l.atom])),
+
+    group_PDB: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.group_PDB.value(l.unit.residueIndex[l.atom])),
+    label_comp_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.label_comp_id.value(l.unit.residueIndex[l.atom])),
+    auth_comp_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.auth_comp_id.value(l.unit.residueIndex[l.atom])),
+    label_seq_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.label_seq_id.value(l.unit.residueIndex[l.atom])),
+    auth_seq_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])),
+    pdbx_PDB_ins_code: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.residues.pdbx_PDB_ins_code.value(l.unit.residueIndex[l.atom]))
 }
 
 const chain = {
-    key: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chainKey.value(l.unit.chainIndex[l.atom])),
+    key: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chainKey.value(l.unit.chainIndex[l.atom])),
 
-    label_asym_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.label_asym_id.value(l.unit.chainIndex[l.atom])),
-    auth_asym_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.auth_asym_id.value(l.unit.chainIndex[l.atom])),
-    label_entity_id: Atom.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.label_entity_id.value(l.unit.chainIndex[l.atom]))
+    label_asym_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.label_asym_id.value(l.unit.chainIndex[l.atom])),
+    auth_asym_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.auth_asym_id.value(l.unit.chainIndex[l.atom])),
+    label_entity_id: Element.property(l => !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.chains.label_entity_id.value(l.unit.chainIndex[l.atom]))
 }
 
-function eK(l: Atom.Location) { return !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.entityKey.value(l.unit.chainIndex[l.atom]); }
+function eK(l: Element.Location) { return !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.hierarchy.entityKey.value(l.unit.chainIndex[l.atom]); }
 
 const entity = {
     key: eK,
 
-    id: Atom.property(l => l.unit.hierarchy.entities.id.value(eK(l))),
-    type: Atom.property(l => l.unit.hierarchy.entities.type.value(eK(l))),
-    src_method: Atom.property(l => l.unit.hierarchy.entities.src_method.value(eK(l))),
-    pdbx_description: Atom.property(l => l.unit.hierarchy.entities.pdbx_description.value(eK(l))),
-    formula_weight: Atom.property(l => l.unit.hierarchy.entities.formula_weight.value(eK(l))),
-    pdbx_number_of_molecules: Atom.property(l => l.unit.hierarchy.entities.pdbx_number_of_molecules.value(eK(l))),
-    details: Atom.property(l => l.unit.hierarchy.entities.details.value(eK(l))),
-    pdbx_mutation: Atom.property(l => l.unit.hierarchy.entities.pdbx_mutation.value(eK(l))),
-    pdbx_fragment: Atom.property(l => l.unit.hierarchy.entities.pdbx_fragment.value(eK(l))),
-    pdbx_ec: Atom.property(l => l.unit.hierarchy.entities.pdbx_ec.value(eK(l)))
+    id: Element.property(l => l.unit.hierarchy.entities.id.value(eK(l))),
+    type: Element.property(l => l.unit.hierarchy.entities.type.value(eK(l))),
+    src_method: Element.property(l => l.unit.hierarchy.entities.src_method.value(eK(l))),
+    pdbx_description: Element.property(l => l.unit.hierarchy.entities.pdbx_description.value(eK(l))),
+    formula_weight: Element.property(l => l.unit.hierarchy.entities.formula_weight.value(eK(l))),
+    pdbx_number_of_molecules: Element.property(l => l.unit.hierarchy.entities.pdbx_number_of_molecules.value(eK(l))),
+    details: Element.property(l => l.unit.hierarchy.entities.details.value(eK(l))),
+    pdbx_mutation: Element.property(l => l.unit.hierarchy.entities.pdbx_mutation.value(eK(l))),
+    pdbx_fragment: Element.property(l => l.unit.hierarchy.entities.pdbx_fragment.value(eK(l))),
+    pdbx_ec: Element.property(l => l.unit.hierarchy.entities.pdbx_ec.value(eK(l)))
 }
 
 const unit = {
-    operator_name: Atom.property(l => l.unit.operator.name),
-    model_num: Atom.property(l => l.unit.model.modelNum)
+    operator_name: Element.property(l => l.unit.operator.name),
+    model_num: Element.property(l => l.unit.model.modelNum)
 }
 
 const Properties = {

+ 23 - 23
src/mol-model/structure/query/selection.ts

@@ -5,38 +5,38 @@
  */
 
 import { HashSet } from 'mol-data/generic'
-import { Structure, AtomSet } from '../structure'
+import { Structure, ElementSet } from '../structure'
 
 // A selection is a pair of a Structure and a sequence of unique AtomSets
 type Selection = Selection.Singletons | Selection.Sequence
 
 namespace Selection {
     // If each element of the selection is a singleton, we can use a more efficient representation.
-    export interface Singletons { readonly kind: 'singletons', readonly structure: Structure, readonly set: AtomSet }
-    export interface Sequence { readonly kind: 'sequence', readonly structure: Structure, readonly sets: ReadonlyArray<AtomSet> }
+    export interface Singletons { readonly kind: 'singletons', readonly structure: Structure, readonly set: ElementSet }
+    export interface Sequence { readonly kind: 'sequence', readonly structure: Structure, readonly sets: ReadonlyArray<ElementSet> }
 
-    export function Singletons(structure: Structure, set: AtomSet): Singletons { return { kind: 'singletons', structure, set } }
-    export function Sequence(structure: Structure, sets: AtomSet[]): Sequence { return { kind: 'sequence', structure, sets } }
+    export function Singletons(structure: Structure, set: ElementSet): Singletons { return { kind: 'singletons', structure, set } }
+    export function Sequence(structure: Structure, sets: ElementSet[]): Sequence { return { kind: 'sequence', structure, sets } }
     export function Empty(structure: Structure): Selection { return Sequence(structure, []); };
 
     export function isSingleton(s: Selection): s is Singletons { return s.kind === 'singletons'; }
-    export function isEmpty(s: Selection) { return isSingleton(s) ? AtomSet.atomCount(s.set) === 0 : s.sets.length === 0; }
+    export function isEmpty(s: Selection) { return isSingleton(s) ? ElementSet.elementCount(s.set) === 0 : s.sets.length === 0; }
 
     export function structureCount(sel: Selection) {
-        if (isSingleton(sel)) return AtomSet.atomCount(sel.set);
+        if (isSingleton(sel)) return ElementSet.elementCount(sel.set);
         return sel.sets.length;
     }
 
     export function unionStructure(sel: Selection): Structure {
         if (isEmpty(sel)) return Structure.Empty(sel.structure.units);
         if (isSingleton(sel)) return Structure.create(sel.structure.units, sel.set);
-        return Structure.create(sel.structure.units, AtomSet.union(sel.sets, sel.structure.atoms));
+        return Structure.create(sel.structure.units, ElementSet.union(sel.sets, sel.structure.elements));
     }
 
     export function getAt(sel: Selection, i: number): Structure {
         if (isSingleton(sel)) {
-            const atom = AtomSet.atomGetAt(sel.set, i);
-            return Structure.create(sel.structure.units, AtomSet.singleton(atom, sel.structure.atoms));
+            const atom = ElementSet.elementGetAt(sel.set, i);
+            return Structure.create(sel.structure.units, ElementSet.singleton(atom, sel.structure.elements));
         }
         return Structure.create(sel.structure.units, sel.sets[i]);
     }
@@ -44,12 +44,12 @@ namespace Selection {
     export function toStructures(sel: Selection): Structure[] {
         const { units } = sel.structure;
         if (isSingleton(sel)) {
-            const ret: Structure[] = new Array(AtomSet.atomCount(sel.set));
-            const atoms = AtomSet.atoms(sel.set);
+            const ret: Structure[] = new Array(ElementSet.elementCount(sel.set));
+            const atoms = ElementSet.elements(sel.set);
             let offset = 0;
             while (atoms.hasNext) {
                 const atom = atoms.move();
-                ret[offset++] = Structure.create(units, AtomSet.singleton(atom, sel.structure.atoms))
+                ret[offset++] = Structure.create(units, ElementSet.singleton(atom, sel.structure.elements))
             }
             return ret;
         } else {
@@ -61,23 +61,23 @@ namespace Selection {
     }
 
     export interface Builder {
-        add(set: AtomSet): void,
+        add(set: ElementSet): void,
         getSelection(): Selection
     }
 
-    function getSelection(structure: Structure, sets: AtomSet[], allSingletons: boolean) {
+    function getSelection(structure: Structure, sets: ElementSet[], allSingletons: boolean) {
         const len = sets.length;
         if (len === 0) return Empty(structure);
-        if (allSingletons) return Singletons(structure, AtomSet.union(sets, structure.atoms));
+        if (allSingletons) return Singletons(structure, ElementSet.union(sets, structure.elements));
         return Sequence(structure, sets);
     }
 
     class LinearBuilderImpl implements Builder {
-        private sets: AtomSet[] = [];
+        private sets: ElementSet[] = [];
         private allSingletons = true;
 
-        add(atoms: AtomSet) {
-            const atomCount = AtomSet.atomCount(atoms);
+        add(atoms: ElementSet) {
+            const atomCount = ElementSet.elementCount(atoms);
             if (atomCount === 0) return;
             this.sets[this.sets.length] = atoms;
             if (atomCount !== 1) this.allSingletons = false;
@@ -89,12 +89,12 @@ namespace Selection {
     }
 
     class HashBuilderImpl implements Builder {
-        private sets: AtomSet[] = [];
+        private sets: ElementSet[] = [];
         private allSingletons = true;
-        private uniqueSets = HashSet(AtomSet.hashCode, AtomSet.areEqual);
+        private uniqueSets = HashSet(ElementSet.hashCode, ElementSet.areEqual);
 
-        add(atoms: AtomSet) {
-            const atomCount = AtomSet.atomCount(atoms);
+        add(atoms: ElementSet) {
+            const atomCount = ElementSet.elementCount(atoms);
             if (atomCount === 0 || !this.uniqueSets.add(atoms)) return;
             this.sets[this.sets.length] = atoms;
             if (atomCount !== 1) this.allSingletons = false;

+ 4 - 4
src/mol-model/structure/structure.ts

@@ -4,11 +4,11 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Atom from './structure/atom'
-import AtomSet from './structure/atom/set'
-import AtomGroup from './structure/atom/group'
+import Element from './structure/element'
+import ElementSet from './structure/element/set'
+import ElementGroup from './structure/element/group'
 import Structure from './structure/structure'
 import Unit from './structure/unit'
 import Symmetry from './structure/symmetry'
 
-export { Atom, AtomSet, AtomGroup, Structure, Unit, Symmetry }
+export { Element, ElementSet, ElementGroup, Structure, Unit, Symmetry }

+ 0 - 71
src/mol-model/structure/structure/atom/group.ts

@@ -1,71 +0,0 @@
-/**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import { OrderedSet } from 'mol-data/int'
-import Unit from '../unit'
-
-interface AtomGroup {
-    atoms: OrderedSet,
-    id: number
-}
-
-namespace AtomGroup {
-    export const Empty = createNew(OrderedSet.Empty)
-
-    export function singleton(idx: number) {
-        return createNew(OrderedSet.ofSingleton(idx));
-    }
-
-    export function createNew(atoms: OrderedSet): AtomGroup {
-        return { id: nextId(), atoms };
-    }
-
-    export function create(unit: Unit, atoms: OrderedSet): AtomGroup {
-        if (OrderedSet.areEqual(atoms, unit.fullGroup.atoms)) return unit.fullGroup;
-        return createNew(atoms);
-    }
-
-    export function createChild(parent: AtomGroup, atoms: OrderedSet): AtomGroup {
-        if (OrderedSet.areEqual(atoms, parent.atoms)) return parent;
-        return createNew(atoms);
-    }
-
-    export function size(group: AtomGroup) { return OrderedSet.size(group.atoms); }
-    export function has(group: AtomGroup, atom: number) { return OrderedSet.has(group.atoms, atom); }
-    export function getAt(group: AtomGroup, i: number) { return OrderedSet.getAt(group.atoms, i); }
-    export function indexOf(group: AtomGroup, atom: number) { return OrderedSet.indexOf(group.atoms, atom); }
-    export function hashCode(group: AtomGroup) { return OrderedSet.hashCode(group.atoms); }
-    export function areEqual(a: AtomGroup, b: AtomGroup) { return OrderedSet.areEqual(a.atoms, b.atoms); }
-
-    export function intersect(a: AtomGroup, b: AtomGroup) {
-        const set = OrderedSet.intersect(a.atoms, b.atoms);
-        if (set === a.atoms) return a;
-        if (set === b.atoms) return b;
-        return createNew(set);
-    }
-
-    export function union(a: AtomGroup, b: AtomGroup) {
-        const set = OrderedSet.union(a.atoms, b.atoms);
-        if (set === a.atoms) return a;
-        if (set === b.atoms) return b;
-        return createNew(set);
-    }
-
-    export function subtract(a: AtomGroup, b: AtomGroup) {
-        const set = OrderedSet.subtract(a.atoms, b.atoms);
-        if (set === a.atoms) return a;
-        return createNew(set);
-    }
-
-    let _id = 0;
-    function nextId() {
-        const ret = _id;
-        _id = (_id + 1) % 0x3fffffff;
-        return ret;
-    }
-}
-
-export default AtomGroup

+ 0 - 60
src/mol-model/structure/structure/atom/set.ts

@@ -1,60 +0,0 @@
-/**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import { SortedArray, Iterator, OrderedSet } from 'mol-data/int'
-import Atom from '../atom'
-import AtomGroup from './group'
-import * as Impl from './impl/set'
-import * as Builders from './impl/set-builder'
-
-/** A map-like representation of grouped atom set */
-namespace AtomSet {
-    export const Empty: AtomSet = Impl.Empty as any;
-
-    export const ofAtoms: (atoms: ArrayLike<Atom>, template: AtomSet) => AtomSet = Impl.ofAtoms as any;
-    export const singleton: (atom: Atom, template: AtomSet) => AtomSet = Impl.singleton as any;
-
-    export const unitCount: (set: AtomSet) => number = Impl.keyCount as any;
-    export const unitIds: (set: AtomSet) => SortedArray = Impl.getKeys as any;
-    export const unitHas: (set: AtomSet, id: number) => boolean = Impl.hasKey as any;
-    export const unitGetId: (set: AtomSet, i: number) => number = Impl.getKey as any;
-
-    export const unitGetById: (set: AtomSet, key: number) => AtomGroup = Impl.getByKey as any;
-    export const unitGetByIndex: (set: AtomSet, i: number) => AtomGroup = Impl.getByIndex as any;
-
-    export const atomCount: (set: AtomSet) => number = Impl.size as any;
-    export const atomHas: (set: AtomSet, x: Atom) => boolean = Impl.hasAtom as any;
-    export const atomIndexOf: (set: AtomSet, x: Atom) => number = Impl.indexOf as any;
-    export const atomGetAt: (set: AtomSet, i: number) => Atom = Impl.getAt as any;
-    export const atoms: (set: AtomSet) => Iterator<Atom> = Impl.values as any;
-
-    export const hashCode: (set: AtomSet) => number = Impl.hashCode as any;
-    export const areEqual: (a: AtomSet, b: AtomSet) => boolean = Impl.areEqual as any;
-    export const areIntersecting: (a: AtomSet, b: AtomSet) => boolean = Impl.areIntersecting as any;
-
-    export const union: (sets: ArrayLike<AtomSet>, template: AtomSet) => AtomSet = Impl.unionMany as any;
-    export const intersect: (a: AtomSet, b: AtomSet) => AtomSet = Impl.intersect as any;
-    export const subtract: (a: AtomSet, b: AtomSet) => AtomSet = Impl.subtract as any;
-
-    export type Builder = Builders.Builder
-    export const LinearBuilder = Builders.LinearBuilder
-    export const UnsortedBuilder = Builders.UnsortedBuilder
-
-    export interface Generator { add(unit: number, set: AtomGroup): void, getSet(): AtomSet }
-    export const Generator: () => Generator = Impl.Generator as any
-
-    export interface TemplateGenerator { add(unit: number, set: OrderedSet): void, getSet(): AtomSet }
-    export const TemplateGenerator: (template: AtomSet) => TemplateGenerator = Impl.TemplateGenerator as any
-
-    // TODO: bounding sphere
-    // TODO: distance, areWithIn?
-    // TODO: check connected
-    // TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
-}
-
-interface AtomSet { '@type': 'atom-set' | Atom['@type'] }
-
-export default AtomSet

+ 12 - 12
src/mol-model/structure/structure/atom.ts → src/mol-model/structure/structure/element.ts

@@ -9,18 +9,18 @@ import Unit from './unit'
 import Structure from './structure'
 
 /** Atom pointer */
-interface Atom { '@type': Tuple['@type'] }
+interface Element { '@type': Tuple['@type'] }
 
-namespace Atom {
-    export const Zero: Atom = Tuple.Zero;
-    export const create: (unit: number, index: number) => Atom = Tuple.create;
-    export const is: (x: any) => x is Atom = Tuple.is;
-    export const unit: (a: Atom) => number = Tuple.fst;
-    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;
+namespace Element {
+    export const Zero: Element = Tuple.Zero;
+    export const create: (unit: number, index: number) => Element = Tuple.create;
+    export const is: (x: any) => x is Element = Tuple.is;
+    export const unit: (e: Element) => number = Tuple.fst;
+    export const index: (e: Element) => number = Tuple.snd;
+    export const areEqual: (e: Element, b: Element) => boolean = Tuple.areEqual;
+    export const hashCode: (e: Element) => number = Tuple.hashCode;
 
-    export function createEmptyArray(n: number): Atom[] { return new Float64Array(n) as any; }
+    export function createEmptyArray(n: number): Element[] { return new Float64Array(n) as any; }
 
     /** All the information required to access atom properties */
     export interface Location { unit: Unit, atom: number }
@@ -28,7 +28,7 @@ namespace Atom {
     export interface Property<T> { (location: Location): T }
     export interface Predicate extends Property<boolean> { }
 
-    export function updateLocation(structure: Structure, l: Location, atom: Atom) {
+    export function updateLocation(structure: Structure, l: Location, atom: Element) {
         l.unit = structure.units[unit(atom)];
         l.atom = index(atom);
         return l;
@@ -37,4 +37,4 @@ namespace Atom {
     export function property<T>(p: Property<T>) { return p; }
 }
 
-export default Atom
+export default Element

+ 71 - 0
src/mol-model/structure/structure/element/group.ts

@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { OrderedSet } from 'mol-data/int'
+import Unit from '../unit'
+
+interface ElementGroup {
+    elements: OrderedSet,
+    id: number
+}
+
+namespace ElementGroup {
+    export const Empty = createNew(OrderedSet.Empty)
+
+    export function singleton(idx: number) {
+        return createNew(OrderedSet.ofSingleton(idx));
+    }
+
+    export function createNew(elements: OrderedSet): ElementGroup {
+        return { id: nextId(), elements };
+    }
+
+    export function create(unit: Unit, elements: OrderedSet): ElementGroup {
+        if (OrderedSet.areEqual(elements, unit.fullGroup.elements)) return unit.fullGroup;
+        return createNew(elements);
+    }
+
+    export function createChild(parent: ElementGroup, elements: OrderedSet): ElementGroup {
+        if (OrderedSet.areEqual(elements, parent.elements)) return parent;
+        return createNew(elements);
+    }
+
+    export function size(group: ElementGroup) { return OrderedSet.size(group.elements); }
+    export function has(group: ElementGroup, element: number) { return OrderedSet.has(group.elements, element); }
+    export function getAt(group: ElementGroup, i: number) { return OrderedSet.getAt(group.elements, i); }
+    export function indexOf(group: ElementGroup, element: number) { return OrderedSet.indexOf(group.elements, element); }
+    export function hashCode(group: ElementGroup) { return OrderedSet.hashCode(group.elements); }
+    export function areEqual(a: ElementGroup, b: ElementGroup) { return OrderedSet.areEqual(a.elements, b.elements); }
+
+    export function intersect(a: ElementGroup, b: ElementGroup) {
+        const set = OrderedSet.intersect(a.elements, b.elements);
+        if (set === a.elements) return a;
+        if (set === b.elements) return b;
+        return createNew(set);
+    }
+
+    export function union(a: ElementGroup, b: ElementGroup) {
+        const set = OrderedSet.union(a.elements, b.elements);
+        if (set === a.elements) return a;
+        if (set === b.elements) return b;
+        return createNew(set);
+    }
+
+    export function subtract(a: ElementGroup, b: ElementGroup) {
+        const set = OrderedSet.subtract(a.elements, b.elements);
+        if (set === a.elements) return a;
+        return createNew(set);
+    }
+
+    let _id = 0;
+    function nextId() {
+        const ret = _id;
+        _id = (_id + 1) % 0x3fffffff;
+        return ret;
+    }
+}
+
+export default ElementGroup

+ 0 - 0
src/mol-model/structure/structure/atom/impl/properties.ts → src/mol-model/structure/structure/element/impl/properties.ts


+ 15 - 15
src/mol-model/structure/structure/atom/impl/set-builder.ts → src/mol-model/structure/structure/element/impl/set-builder.ts

@@ -4,8 +4,8 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import AtomSet from '../set'
-import Atom from '../../atom'
+import ElementSet from '../set'
+import Element from '../../element'
 import { OrderedSet, IntMap } from 'mol-data/int'
 import { sortArray } from 'mol-data/util/sort'
 
@@ -14,28 +14,28 @@ export class Builder {
     private units = IntMap.Mutable<number[]>();
     private currentUnit: number[] = [];
 
-    atomCount = 0;
+    elementCount = 0;
 
-    add(u: number, a: number) {
+    add(u: number, e: number) {
         const unit = this.units.get(u);
-        if (!!unit) { unit[unit.length] = a; }
+        if (!!unit) { unit[unit.length] = e; }
         else {
-            this.units.set(u, [a]);
+            this.units.set(u, [e]);
             this.keys[this.keys.length] = u;
         }
-        this.atomCount++;
+        this.elementCount++;
     }
 
     beginUnit() { this.currentUnit = this.currentUnit.length > 0 ? [] : this.currentUnit; }
-    addToUnit(a: number) { this.currentUnit[this.currentUnit.length] = a; this.atomCount++; }
+    addToUnit(a: number) { this.currentUnit[this.currentUnit.length] = a; this.elementCount++; }
     commitUnit(u: number) {
         if (this.currentUnit.length === 0) return;
         this.keys[this.keys.length] = u;
         this.units.set(u, this.currentUnit);
     }
 
-    getSet(): AtomSet {
-        const generator = AtomSet.TemplateGenerator(this.parent);
+    getSet(): ElementSet {
+        const generator = ElementSet.TemplateGenerator(this.parent);
 
         for (let i = 0, _i = this.keys.length; i < _i; i++) {
             const k = this.keys[i];
@@ -48,18 +48,18 @@ export class Builder {
         return generator.getSet();
     }
 
-    singleton(): Atom {
+    singleton(): Element {
         const u = this.keys[0];
-        return Atom.create(u, this.units.get(u)[0]);
+        return Element.create(u, this.units.get(u)[0]);
     }
 
-    constructor(private parent: AtomSet, private sorted: boolean) { }
+    constructor(private parent: ElementSet, private sorted: boolean) { }
 }
 
-export function LinearBuilder(parent: AtomSet) {
+export function LinearBuilder(parent: ElementSet) {
     return new Builder(parent, true);
 }
 
-export function UnsortedBuilder(parent: AtomSet) {
+export function UnsortedBuilder(parent: ElementSet) {
     return new Builder(parent, false);
 }

+ 80 - 80
src/mol-model/structure/structure/atom/impl/set.ts → src/mol-model/structure/structure/element/impl/set.ts

@@ -7,83 +7,83 @@
 import { SortedArray, Interval, Iterator, OrderedSet as OS, IntMap } from 'mol-data/int'
 import { sortArray } from 'mol-data/util/sort'
 import { hash1 } from 'mol-data/util/hash-functions'
-import Atom from '../../atom'
-import AtomGroup from '../group'
+import Element from '../../element'
+import ElementGroup from '../group'
 
 /** Long and painful implementation starts here */
 
-export type AtomSetImpl = { groups: IntMap<AtomGroup>, offsets: Int32Array, hashCode: number, keys: SortedArray }
+export type ElementSetImpl = { groups: IntMap<ElementGroup>, offsets: Int32Array, hashCode: number, keys: SortedArray }
 
-export const Empty: AtomSetImpl = { groups: IntMap.Empty, offsets: new Int32Array(1), hashCode: 0, keys: SortedArray.Empty };
+export const Empty: ElementSetImpl = { groups: IntMap.Empty, offsets: new Int32Array(1), hashCode: 0, keys: SortedArray.Empty };
 
-export function ofAtoms(atoms: ArrayLike<Atom>, template: AtomSetImpl): AtomSetImpl {
-    return ofAtomsImpl(atoms, template);
+export function ofElements(elements: ArrayLike<Element>, template: ElementSetImpl): ElementSetImpl {
+    return ofElementsImpl(elements, template);
 }
 
-export function singleton(atom: Atom, template: AtomSetImpl) {
-    return singletonImpl(atom, template);
+export function singleton(element: Element, template: ElementSetImpl) {
+    return singletonImpl(element, template);
 }
 
-export function getKeys(set: AtomSetImpl): SortedArray {
+export function getKeys(set: ElementSetImpl): SortedArray {
     return set.keys;
 }
 
-export function keyCount(set: AtomSetImpl): number {
+export function keyCount(set: ElementSetImpl): number {
     return set.keys.length;
 }
 
-export function hasKey(set: AtomSetImpl, key: number): boolean {
+export function hasKey(set: ElementSetImpl, key: number): boolean {
     return set.groups.has(key);
 }
 
-export function getKey(set: AtomSetImpl, index: number): number {
+export function getKey(set: ElementSetImpl, index: number): number {
     return set.keys[index];
 }
 
-export function hasAtom(set: AtomSetImpl, t: Atom): boolean {
-    const os = set.groups.get(Atom.unit(t));
-    return !!os && AtomGroup.has(os, Atom.index(t));
+export function hasAtom(set: ElementSetImpl, t: Element): boolean {
+    const os = set.groups.get(Element.unit(t));
+    return !!os && ElementGroup.has(os, Element.index(t));
 }
 
-export function getByKey(set: AtomSetImpl, key: number): AtomGroup {
-    return set.groups.get(key) || AtomGroup.Empty;
+export function getByKey(set: ElementSetImpl, key: number): ElementGroup {
+    return set.groups.get(key) || ElementGroup.Empty;
 }
 
-export function getByIndex(set: AtomSetImpl, index: number): AtomGroup {
+export function getByIndex(set: ElementSetImpl, index: number): ElementGroup {
     const key = set.keys[index];
-    return set.groups.get(key) || AtomGroup.Empty;
+    return set.groups.get(key) || ElementGroup.Empty;
 }
 
-export function getAt(set: AtomSetImpl, i: number): Atom {
+export function getAt(set: ElementSetImpl, i: number): Element {
     const { offsets, keys } = set;
     const o = getOffsetIndex(offsets, i);
-    if (o >= offsets.length - 1) return Atom.Zero;
+    if (o >= offsets.length - 1) return Element.Zero;
     const k = keys[o];
-    const e = AtomGroup.getAt(set.groups.get(k), i - offsets[o]);
-    return Atom.create(k, e);
+    const e = ElementGroup.getAt(set.groups.get(k), i - offsets[o]);
+    return Element.create(k, e);
 }
 
-export function indexOf(set: AtomSetImpl, t: Atom) {
+export function indexOf(set: ElementSetImpl, t: Element) {
     const { keys } = set;
-    const u = Atom.unit(t);
+    const u = Element.unit(t);
     const setIdx = SortedArray.indexOf(keys, u);
     if (setIdx < 0) return -1;
-    const o = AtomGroup.indexOf(set.groups.get(u), Atom.index(t));
+    const o = ElementGroup.indexOf(set.groups.get(u), Element.index(t));
     if (o < 0) return -1;
     return set.offsets[setIdx] + o;
 }
 
 /** Number elements in the "child" sets */
-export function size(set: AtomSetImpl) {
+export function size(set: ElementSetImpl) {
     return set.offsets[set.offsets.length - 1];
 }
 
-export function hashCode(set: AtomSetImpl) {
+export function hashCode(set: ElementSetImpl) {
     if (set.hashCode !== -1) return set.hashCode;
     return computeHash(set);
 }
 
-export function areEqual(a: AtomSetImpl, b: AtomSetImpl) {
+export function areEqual(a: ElementSetImpl, b: ElementSetImpl) {
     if (a === b) return true;
     if (size(a) !== size(a)) return false;
 
@@ -93,12 +93,12 @@ export function areEqual(a: AtomSetImpl, b: AtomSetImpl) {
     const { groups: bG } = b;
     for (let i = 0, _i = keys.length; i < _i; i++) {
         const k = keys[i];
-        if (!AtomGroup.areEqual(aG.get(k), bG.get(k))) return false;
+        if (!ElementGroup.areEqual(aG.get(k), bG.get(k))) return false;
     }
     return true;
 }
 
-export function areIntersecting(a: AtomSetImpl, b: AtomSetImpl) {
+export function areIntersecting(a: ElementSetImpl, b: ElementSetImpl) {
     if (a === b) return true;
     const keysA = a.keys, keysB = b.keys;
     if (!SortedArray.areIntersecting(a.keys, b.keys)) return false;
@@ -109,12 +109,12 @@ export function areIntersecting(a: AtomSetImpl, b: AtomSetImpl) {
     for (let i = start; i < end; i++) {
         const k = keysA[i];
         const ak = aG.get(k), bk = bG.get(k);
-        if (!!ak && !!bk && OS.areIntersecting(ak.atoms, bk.atoms)) return true;
+        if (!!ak && !!bk && OS.areIntersecting(ak.elements, bk.elements)) return true;
     }
     return false;
 }
 
-export function intersect(a: AtomSetImpl, b: AtomSetImpl) {
+export function intersect(a: ElementSetImpl, b: ElementSetImpl) {
     if (a === b) return a;
 
     const keysA = a.keys, keysB = b.keys;
@@ -130,12 +130,12 @@ export function intersect(a: AtomSetImpl, b: AtomSetImpl) {
         const bk = bG.get(k);
         if (!bk) continue;
         const ak = aG.get(k);
-        generator.add(k, AtomGroup.intersect(aG.get(k), bk), ak, bk);
+        generator.add(k, ElementGroup.intersect(aG.get(k), bk), ak, bk);
     }
     return generator.getSet();
 }
 
-export function subtract(a: AtomSetImpl, b: AtomSetImpl) {
+export function subtract(a: ElementSetImpl, b: ElementSetImpl) {
     if (a === b) return Empty;
 
     const keysA = a.keys, keysB = b.keys;
@@ -155,7 +155,7 @@ export function subtract(a: AtomSetImpl, b: AtomSetImpl) {
         const k = keysA[i];
         const ak = aG.get(k), bk = bG.get(k);
         if (!!bk) {
-            const subtraction = AtomGroup.subtract(ak, bk);
+            const subtraction = ElementGroup.subtract(ak, bk);
             generator.addA(k, subtraction, ak);
         } else {
             generator.addA(k, ak, ak);
@@ -169,11 +169,11 @@ export function subtract(a: AtomSetImpl, b: AtomSetImpl) {
     return generator.getSet();
 }
 
-export function unionMany(sets: ArrayLike<AtomSetImpl>, template: AtomSetImpl) {
+export function unionMany(sets: ArrayLike<ElementSetImpl>, template: ElementSetImpl) {
     return findUnion(sets, template);
 }
 
-class ElementsIterator implements Iterator<Atom> {
+class ElementsIterator implements Iterator<Element> {
     private unit: number = 0;
     private keyCount: number;
     private setIndex = -1;
@@ -184,8 +184,8 @@ class ElementsIterator implements Iterator<Atom> {
     hasNext: boolean = false;
 
     move() {
-        if (!this.hasNext) return Atom.Zero;
-        const ret = Atom.create(this.unit, OS.getAt(this.currentSet, this.currentIndex++));
+        if (!this.hasNext) return Element.Zero;
+        const ret = Element.create(this.unit, OS.getAt(this.currentSet, this.currentIndex++));
         if (this.currentIndex >= this.currentSize) this.advance();
         return ret;
     }
@@ -196,27 +196,27 @@ class ElementsIterator implements Iterator<Atom> {
             return false;
         }
         this.unit = this.elements.keys[this.setIndex];
-        this.currentSet = this.elements.groups.get(this.unit).atoms;
+        this.currentSet = this.elements.groups.get(this.unit).elements;
         this.currentIndex = 0;
         this.currentSize = OS.size(this.currentSet);
         return true;
     }
 
-    constructor(private elements: AtomSetImpl) {
+    constructor(private elements: ElementSetImpl) {
         this.keyCount = elements.keys.length;
         this.hasNext = this.keyCount > 0;
         this.advance();
     }
 }
 
-export function values(set: AtomSetImpl): Iterator<Atom> {
+export function values(set: ElementSetImpl): Iterator<Element> {
     return new ElementsIterator(set);
 }
 
 export class TemplateAtomSetGenerator {
     private keys: number[] = [];
-    private groups = IntMap.Mutable<AtomGroup>();
-    private templateGroups: IntMap<AtomGroup>;
+    private groups = IntMap.Mutable<ElementGroup>();
+    private templateGroups: IntMap<ElementGroup>;
     private equalGroups = 0;
 
     add(unit: number, set: OS) {
@@ -224,44 +224,44 @@ export class TemplateAtomSetGenerator {
         this.keys[this.keys.length] = unit;
         if (this.templateGroups.has(unit)) {
             const t = this.templateGroups.get(unit);
-            if (OS.areEqual(t.atoms, set)) {
+            if (OS.areEqual(t.elements, set)) {
                 this.groups.set(unit, t);
                 this.equalGroups++;
             } else {
-                this.groups.set(unit, AtomGroup.createNew(set));
+                this.groups.set(unit, ElementGroup.createNew(set));
             }
         } else {
-            this.groups.set(unit, AtomGroup.createNew(set));
+            this.groups.set(unit, ElementGroup.createNew(set));
         }
     }
 
-    getSet(): AtomSetImpl {
+    getSet(): ElementSetImpl {
         if (this.equalGroups === this.template.keys.length && this.equalGroups === this.keys.length) {
             return this.template;
         }
         return create(this.keys, this.groups);
     }
 
-    constructor(private template: AtomSetImpl) {
+    constructor(private template: ElementSetImpl) {
         this.templateGroups = template.groups;
     }
 }
 
-export function TemplateGenerator(template: AtomSetImpl) {
+export function TemplateGenerator(template: ElementSetImpl) {
     return new TemplateAtomSetGenerator(template);
 }
 
 export class AtomSetGenerator {
     private keys: number[] = [];
-    private groups = IntMap.Mutable<AtomGroup>();
+    private groups = IntMap.Mutable<ElementGroup>();
 
-    add(unit: number, group: AtomGroup) {
-        if (AtomGroup.size(group) === 0) return;
+    add(unit: number, group: ElementGroup) {
+        if (ElementGroup.size(group) === 0) return;
         this.keys[this.keys.length] = unit;
         this.groups.set(unit, group);
     }
 
-    getSet(): AtomSetImpl {
+    getSet(): ElementSetImpl {
         return create(this.keys, this.groups);
     }
 }
@@ -273,42 +273,42 @@ export function Generator() {
 /** When adding groups, compare them to existing ones. If they all match, return the whole original set. */
 class ChildGenerator {
     private keys: number[] = [];
-    private groups = IntMap.Mutable<AtomGroup>();
+    private groups = IntMap.Mutable<ElementGroup>();
     private aEqual = 0;
     private bEqual = 0;
 
-    add(unit: number, group: AtomGroup, a: AtomGroup, b: AtomGroup) {
-        if (AtomGroup.size(group) === 0) return;
+    add(unit: number, group: ElementGroup, a: ElementGroup, b: ElementGroup) {
+        if (ElementGroup.size(group) === 0) return;
         if (a === group) this.aEqual++;
         if (b === group) this.bEqual++;
         this.keys[this.keys.length] = unit;
         this.groups.set(unit, group);
     }
 
-    addA(unit: number, group: AtomGroup, a: AtomGroup) {
-        if (AtomGroup.size(group) === 0) return;
+    addA(unit: number, group: ElementGroup, a: ElementGroup) {
+        if (ElementGroup.size(group) === 0) return;
 
         if (a === group) this.aEqual++;
         this.keys[this.keys.length] = unit;
         this.groups.set(unit, group);
     }
 
-    constructor(private a: AtomSetImpl, private b: AtomSetImpl) {
+    constructor(private a: ElementSetImpl, private b: ElementSetImpl) {
     }
 
-    getSet(): AtomSetImpl {
+    getSet(): ElementSetImpl {
         if (this.aEqual === this.a.keys.length) return this.a;
         if (this.bEqual === this.b.keys.length) return this.b;
         return create(this.keys, this.groups);
     }
 }
 
-function create(keys: number[], groups: IntMap<AtomGroup>): AtomSetImpl {
+function create(keys: number[], groups: IntMap<ElementGroup>): ElementSetImpl {
     sortArray(keys);
     let runningSize = 0;
     const offsets = new Int32Array(keys.length + 1);
     for (let i = 0, _i = keys.length; i < _i; i++) {
-        runningSize += AtomGroup.size(groups.get(keys[i]));
+        runningSize += ElementGroup.size(groups.get(keys[i]));
         offsets[i + 1] = runningSize;
     }
     return { keys: SortedArray.ofSortedArray(keys), groups: IntMap.asImmutable(groups), offsets, hashCode: -1 };
@@ -336,14 +336,14 @@ function normalizeArray(xs: number[]): number[] {
     return xs;
 }
 
-function ofAtomsImpl(xs: ArrayLike<Atom>, template: AtomSetImpl) {
+function ofElementsImpl(xs: ArrayLike<Element>, template: ElementSetImpl) {
     if (xs.length === 0) return Empty;
 
     const elements = IntMap.Mutable<number[]>();
     const keys: number[] = [];
     for (let i = 0, _i = xs.length; i < _i; i++) {
         const x = xs[i];
-        const u = Atom.unit(x), v = Atom.index(x);
+        const u = Element.unit(x), v = Element.index(x);
         if (elements.has(u)) {
             const set = elements.get(u);
             set[set.length] = v;
@@ -362,18 +362,18 @@ function ofAtomsImpl(xs: ArrayLike<Atom>, template: AtomSetImpl) {
     return generator.getSet();
 }
 
-function singletonImpl(atom: Atom, template: AtomSetImpl) {
-    const k = Atom.unit(atom), i = Atom.index(atom);
+function singletonImpl(element: Element, template: ElementSetImpl) {
+    const k = Element.unit(element), i = Element.index(element);
     const { groups } = template;
-    const gs = IntMap.Mutable<AtomGroup>();
+    const gs = IntMap.Mutable<ElementGroup>();
     if (groups.has(k)) {
         const g = groups.get(k);
-        if (AtomGroup.size(g) === 1 && AtomGroup.getAt(g, 0) === i) {
+        if (ElementGroup.size(g) === 1 && ElementGroup.getAt(g, 0) === i) {
             gs.set(k, g);
             return create([k], gs);
         }
     }
-    gs.set(k, AtomGroup.createNew(OS.ofSingleton(i)));
+    gs.set(k, ElementGroup.createNew(OS.ofSingleton(i)));
     return create([k], gs);
 }
 
@@ -392,13 +392,13 @@ function getOffsetIndex(xs: ArrayLike<number>, value: number) {
     return value < xs[min] ? min - 1 : min;
 }
 
-function computeHash(set: AtomSetImpl) {
+function computeHash(set: ElementSetImpl) {
     const { keys, groups } = set;
     let hash = 23;
     for (let i = 0, _i = keys.length; i < _i; i++) {
         const k = keys[i];
         hash = (31 * hash + k) | 0;
-        hash = (31 * hash + AtomGroup.hashCode(groups.get(k))) | 0;
+        hash = (31 * hash + ElementGroup.hashCode(groups.get(k))) | 0;
     }
     hash = (31 * hash + size(set)) | 0;
     hash = hash1(hash);
@@ -406,13 +406,13 @@ function computeHash(set: AtomSetImpl) {
     return hash;
 }
 
-function findUnion(sets: ArrayLike<AtomSetImpl>, template: AtomSetImpl) {
+function findUnion(sets: ArrayLike<ElementSetImpl>, template: ElementSetImpl) {
     if (!sets.length) return Empty;
     if (sets.length === 1) return sets[0];
     if (sets.length === 2 && sets[0] === sets[1]) return sets[0];
 
     const keys: number[] = [];
-    const groups = IntMap.Mutable<AtomGroup>();
+    const groups = IntMap.Mutable<ElementGroup>();
     for (let i = 0, _i = sets.length; i < _i; i++) {
         unionInto(keys, groups, sets[i]);
     }
@@ -420,12 +420,12 @@ function findUnion(sets: ArrayLike<AtomSetImpl>, template: AtomSetImpl) {
     return normalizeUnion(keys, groups, template);
 }
 
-function normalizeUnion(keys: number[], groups: IntMap.Mutable<AtomGroup>, template: AtomSetImpl) {
+function normalizeUnion(keys: number[], groups: IntMap.Mutable<ElementGroup>, template: ElementSetImpl) {
     let equalCount = 0;
-    let tg = template.groups, a: AtomGroup, t: AtomGroup;
+    let tg = template.groups, a: ElementGroup, t: ElementGroup;
     for (let i = 0, _i = keys.length; i < _i; i++) {
         const k = keys[i];
-        if (tg.has(k) && AtomGroup.areEqual(a = groups.get(k), t = tg.get(k))) {
+        if (tg.has(k) && ElementGroup.areEqual(a = groups.get(k), t = tg.get(k))) {
             groups.set(k, t);
             equalCount++;
         }
@@ -433,13 +433,13 @@ function normalizeUnion(keys: number[], groups: IntMap.Mutable<AtomGroup>, templ
     return equalCount === template.keys.length && equalCount === keys.length ? template : create(keys, groups);
 }
 
-function unionInto(keys: number[], groups: IntMap.Mutable<AtomGroup>, a: AtomSetImpl) {
+function unionInto(keys: number[], groups: IntMap.Mutable<ElementGroup>, a: ElementSetImpl) {
     const setKeys = a.keys;
     const { groups: aG } = a;
     for (let i = 0, _i = setKeys.length; i < _i; i++) {
         const k = setKeys[i];
         if (groups.has(k)) {
-            groups.set(k, AtomGroup.union(aG.get(k), groups.get(k)))
+            groups.set(k, ElementGroup.union(aG.get(k), groups.get(k)))
         } else {
             keys[keys.length] = k;
             groups.set(k, aG.get(k));

+ 60 - 0
src/mol-model/structure/structure/element/set.ts

@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { SortedArray, Iterator, OrderedSet } from 'mol-data/int'
+import Element from '../element'
+import ElementGroup from './group'
+import * as Impl from './impl/set'
+import * as Builders from './impl/set-builder'
+
+/** A map-like representation of grouped atom set */
+namespace ElementSet {
+    export const Empty: ElementSet = Impl.Empty as any;
+
+    export const ofAtoms: (elements: ArrayLike<Element>, template: ElementSet) => ElementSet = Impl.ofElements as any;
+    export const singleton: (element: Element, template: ElementSet) => ElementSet = Impl.singleton as any;
+
+    export const unitCount: (set: ElementSet) => number = Impl.keyCount as any;
+    export const unitIds: (set: ElementSet) => SortedArray = Impl.getKeys as any;
+    export const unitHas: (set: ElementSet, id: number) => boolean = Impl.hasKey as any;
+    export const unitGetId: (set: ElementSet, i: number) => number = Impl.getKey as any;
+
+    export const unitGetById: (set: ElementSet, key: number) => ElementGroup = Impl.getByKey as any;
+    export const unitGetByIndex: (set: ElementSet, i: number) => ElementGroup = Impl.getByIndex as any;
+
+    export const elementCount: (set: ElementSet) => number = Impl.size as any;
+    export const elementHas: (set: ElementSet, x: Element) => boolean = Impl.hasAtom as any;
+    export const elementIndexOf: (set: ElementSet, x: Element) => number = Impl.indexOf as any;
+    export const elementGetAt: (set: ElementSet, i: number) => Element = Impl.getAt as any;
+    export const elements: (set: ElementSet) => Iterator<Element> = Impl.values as any;
+
+    export const hashCode: (set: ElementSet) => number = Impl.hashCode as any;
+    export const areEqual: (a: ElementSet, b: ElementSet) => boolean = Impl.areEqual as any;
+    export const areIntersecting: (a: ElementSet, b: ElementSet) => boolean = Impl.areIntersecting as any;
+
+    export const union: (sets: ArrayLike<ElementSet>, template: ElementSet) => ElementSet = Impl.unionMany as any;
+    export const intersect: (a: ElementSet, b: ElementSet) => ElementSet = Impl.intersect as any;
+    export const subtract: (a: ElementSet, b: ElementSet) => ElementSet = Impl.subtract as any;
+
+    export type Builder = Builders.Builder
+    export const LinearBuilder = Builders.LinearBuilder
+    export const UnsortedBuilder = Builders.UnsortedBuilder
+
+    export interface Generator { add(unit: number, set: ElementGroup): void, getSet(): ElementSet }
+    export const Generator: () => Generator = Impl.Generator as any
+
+    export interface TemplateGenerator { add(unit: number, set: OrderedSet): void, getSet(): ElementSet }
+    export const TemplateGenerator: (template: ElementSet) => TemplateGenerator = Impl.TemplateGenerator as any
+
+    // TODO: bounding sphere
+    // TODO: distance, areWithIn?
+    // TODO: check connected
+    // TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
+}
+
+interface ElementSet { '@type': 'element-set' | Element['@type'] }
+
+export default ElementSet

+ 23 - 23
src/mol-model/structure/structure/structure.ts

@@ -9,20 +9,20 @@ import { UniqueArray } from 'mol-data/generic'
 import SymmetryOperator from 'mol-math/geometry/symmetry-operator'
 import { Model, Format } from '../model'
 import Unit from './unit'
-import AtomSet from './atom/set'
-import AtomGroup from './atom/group'
-import Atom from './atom'
+import ElementSet from './element/set'
+import ElementGroup from './element/group'
+import Element from './element'
 
-// A structure is a pair of "units" and an atom set.
-// Each unit contains the data and transformation of its corresponding atoms.
+// A structure is a pair of "units" and an element set.
+// Each unit contains the data and transformation of its corresponding elements.
 interface Structure {
     readonly units: ReadonlyArray<Unit>,
-    readonly atoms: AtomSet
+    readonly elements: ElementSet
 }
 
 namespace Structure {
-    export function create(units: ReadonlyArray<Unit>, atoms: AtomSet): Structure { return { units, atoms }; }
-    export function Empty(units: ReadonlyArray<Unit>): Structure { return create(units, AtomSet.Empty); };
+    export function create(units: ReadonlyArray<Unit>, elements: ElementSet): Structure { return { units, elements }; }
+    export function Empty(units: ReadonlyArray<Unit>): Structure { return create(units, ElementSet.Empty); };
 
     export function ofData(format: Format) {
         const models = Model.create(format);
@@ -34,7 +34,7 @@ namespace Structure {
         const builder = Builder();
 
         for (let c = 0; c < chains.count; c++) {
-            const group = AtomGroup.createNew(OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1]));
+            const group = ElementGroup.createNew(OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1]));
             const unit = Unit.createAtomic(model, SymmetryOperator.Default, group);
             builder.add(unit, unit.fullGroup);
         }
@@ -43,38 +43,38 @@ namespace Structure {
     }
 
     export interface Builder {
-        add(unit: Unit, atoms: AtomGroup): void,
+        add(unit: Unit, elements: ElementGroup): void,
         addUnit(unit: Unit): void,
-        setAtoms(unitId: number, atoms: AtomGroup): void,
+        setElements(unitId: number, elements: ElementGroup): void,
         getStructure(): Structure,
-        readonly atomCount: number
+        readonly elementCount: number
     }
 
     class BuilderImpl implements Builder {
         private _unitId = 0;
         private units: Unit[] = [];
-        private atoms = AtomSet.Generator();
-        atomCount = 0;
+        private elements = ElementSet.Generator();
+        elementCount = 0;
 
-        add(unit: Unit, atoms: AtomGroup) { const id = this.addUnit(unit); this.setAtoms(id, atoms); }
+        add(unit: Unit, elements: ElementGroup) { const id = this.addUnit(unit); this.setElements(id, elements); }
         addUnit(unit: Unit) { const id = this._unitId++; this.units[id] = unit; return id; }
-        setAtoms(unitId: number, atoms: AtomGroup) { this.atoms.add(unitId, atoms); this.atomCount += AtomGroup.size(atoms); }
-        getStructure(): Structure { return this.atomCount > 0 ? Structure.create(this.units, this.atoms.getSet()) : Empty(this.units); }
+        setElements(unitId: number, elements: ElementGroup) { this.elements.add(unitId, elements); this.elementCount += ElementGroup.size(elements); }
+        getStructure(): Structure { return this.elementCount > 0 ? Structure.create(this.units, this.elements.getSet()) : Empty(this.units); }
     }
 
     export function Builder(): Builder { return new BuilderImpl(); }
 
     /** Transient = location gets overwritten when move() is called. */
-    export function atomLocationsTransient(s: Structure): Iterator<Atom.Location> {
-        const l = Atom.Location();
-        const update = Atom.updateLocation;
-        return Iterator.map(AtomSet.atoms(s.atoms), a => update(s, l, a));
+    export function elementLocationsTransient(s: Structure): Iterator<Element.Location> {
+        const l = Element.Location();
+        const update = Element.updateLocation;
+        return Iterator.map(ElementSet.elements(s.elements), a => update(s, l, a));
     }
 
     export function getModels(s: Structure) {
-        const { units, atoms } = s;
+        const { units, elements } = s;
         const arr = UniqueArray.create<Model['id'], Model>();
-        const ids = AtomSet.unitIds(atoms);
+        const ids = ElementSet.unitIds(elements);
         for (let i = 0; i < ids.length; i++) {
             const u = units[ids[i]];
             UniqueArray.add(arr, u.model.id, u.model);

+ 4 - 4
src/mol-model/structure/structure/symmetry.ts

@@ -5,7 +5,7 @@
  */
 
 import Structure from './structure'
-import AtomSet from './atom/set'
+import ElementSet from './element/set'
 import Unit from './unit'
 import { Selection } from '../query'
 import { ModelSymmetry } from '../model'
@@ -28,14 +28,14 @@ function buildAssemblyImpl(structure: Structure, name: string) {
     for (const g of assembly.operatorGroups) {
         const selection = g.selector(structure);
         if (Selection.structureCount(selection) === 0) continue;
-        const { units, atoms } = Selection.unionStructure(selection);
+        const { units, elements } = Selection.unionStructure(selection);
 
-        const unitIds = AtomSet.unitIds(atoms);
+        const unitIds = ElementSet.unitIds(elements);
 
         for (const oper of g.operators) {
             for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) {
                 const unit = units[unitIds[uI]];
-                assembler.add(Unit.withOperator(unit, oper), AtomSet.unitGetByIndex(atoms, uI));
+                assembler.add(Unit.withOperator(unit, oper), ElementSet.unitGetByIndex(elements, uI));
             }
         }
     }

+ 4 - 4
src/mol-model/structure/structure/unit.ts

@@ -5,7 +5,7 @@
  */
 
 import SymmetryOperator from 'mol-math/geometry/symmetry-operator'
-import AtomGroup from './atom/group'
+import ElementGroup from './element/group'
 import { Model } from '../model'
 
 // A building block of a structure that corresponds to an atomic or a coarse grained representation
@@ -27,7 +27,7 @@ namespace Unit {
         // Things like inter-unit bonds or spatial lookups
         // can be be implemented efficiently as "views" of the
         // full group.
-        readonly fullGroup: AtomGroup,
+        readonly fullGroup: ElementGroup,
 
         readonly hierarchy: Model['hierarchy'],
     }
@@ -54,7 +54,7 @@ namespace Unit {
         readonly kind: Unit.Kind.Coarse
     }
 
-    export function createAtomic(model: Model, operator: SymmetryOperator, fullGroup: AtomGroup): Unit {
+    export function createAtomic(model: Model, operator: SymmetryOperator, fullGroup: ElementGroup): Unit {
         const h = model.hierarchy;
         const { invariantPosition, position, x, y, z } = SymmetryOperator.createMapping(operator, model.conformation);
 
@@ -73,7 +73,7 @@ namespace Unit {
         };
     }
 
-    export function createCoarse(model: Model, operator: SymmetryOperator, fullGroup: AtomGroup): Unit {
+    export function createCoarse(model: Model, operator: SymmetryOperator, fullGroup: ElementGroup): Unit {
         throw 'not implemented'
     }
 

+ 10 - 10
src/perf-tests/sets.ts

@@ -1,6 +1,6 @@
 import * as B from 'benchmark'
 import { Tuple, Segmentation, OrderedSet as OrdSet } from 'mol-data/int'
-import { AtomSet } from 'mol-model/structure'
+import { ElementSet } from 'mol-model/structure'
 
 // export namespace Iteration {
 //     const U = 1000, V = 2500;
@@ -15,7 +15,7 @@ import { AtomSet } from 'mol-model/structure'
 //         }
 //         sets[i * i] = OrdSet.ofSortedArray(set);
 //     }
-//     const ms = AtomSet.create(sets);
+//     const ms = ElementSet.create(sets);
 
 //     export function native() {
 //         let s = 0;
@@ -25,7 +25,7 @@ import { AtomSet } from 'mol-model/structure'
 
 //     export function iterators() {
 //         let s = 0;
-//         const it = AtomSet.atoms(ms);
+//         const it = ElementSet.atoms(ms);
 //         while (it.hasNext) {
 //             const v = it.move();
 //             s += Tuple.snd(v);
@@ -35,15 +35,15 @@ import { AtomSet } from 'mol-model/structure'
 
 //     export function elementAt() {
 //         let s = 0;
-//         for (let i = 0, _i = AtomSet.atomCount(ms); i < _i; i++) s += Tuple.snd(AtomSet.atomGetAt(ms, i));
+//         for (let i = 0, _i = ElementSet.atomCount(ms); i < _i; i++) s += Tuple.snd(ElementSet.atomGetAt(ms, i));
 //         return s;
 //     }
 
 //     export function manual() {
 //         let s = 0;
-//         const keys = AtomSet.unitIds(ms);
+//         const keys = ElementSet.unitIds(ms);
 //         for (let i = 0, _i = OrdSet.size(keys); i < _i; i++) {
-//             const set = AtomSet.unitGetById(ms, OrdSet.getAt(keys, i));
+//             const set = ElementSet.unitGetById(ms, OrdSet.getAt(keys, i));
 //             for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
 //                 s += OrdSet.getAt(set, j);
 //             }
@@ -53,8 +53,8 @@ import { AtomSet } from 'mol-model/structure'
 
 //     export function manual1() {
 //         let s = 0;
-//         for (let i = 0, _i = AtomSet.unitCount(ms); i < _i; i++) {
-//             const set = AtomSet.unitGetByIndex(ms, i);
+//         for (let i = 0, _i = ElementSet.unitCount(ms); i < _i; i++) {
+//             const set = ElementSet.unitGetByIndex(ms, i);
 //             for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
 //                 s += OrdSet.getAt(set, j);
 //             }
@@ -200,7 +200,7 @@ export namespace Union {
 
 export namespace Build {
     function createSorted() {
-        const b = AtomSet.LinearBuilder(AtomSet.Empty);
+        const b = ElementSet.LinearBuilder(ElementSet.Empty);
         for (let i = 0; i < 10; i++) {
             for (let j = 0; j < 1000; j++) {
                 b.add(i, j);
@@ -210,7 +210,7 @@ export namespace Build {
     }
 
     function createByUnit() {
-        const b = AtomSet.LinearBuilder(AtomSet.Empty);
+        const b = ElementSet.LinearBuilder(ElementSet.Empty);
         for (let i = 0; i < 10; i++) {
             b.beginUnit();
             for (let j = 0; j < 1000; j++) {

+ 36 - 36
src/perf-tests/structure.ts

@@ -11,7 +11,7 @@ import * as fs from 'fs'
 import fetch from 'node-fetch'
 import CIF from 'mol-io/reader/cif'
 
-import { Structure, Model, Queries as Q, Atom, AtomGroup, AtomSet, Selection, Symmetry } from 'mol-model/structure'
+import { Structure, Model, Queries as Q, Element, ElementGroup, ElementSet, Selection, Symmetry } from 'mol-model/structure'
 import { Segmentation } from 'mol-data/int'
 
 import to_mmCIF from 'mol-model/structure/export/mmcif'
@@ -117,20 +117,20 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumProperty(structure: Structure, p: Atom.Property<number>) {
-        const { atoms, units } = structure;
-        const unitIds = AtomSet.unitIds(atoms);
-        const l = Atom.Location();
+    function sumProperty(structure: Structure, p: Element.Property<number>) {
+        const { elements, units } = structure;
+        const unitIds = ElementSet.unitIds(elements);
+        const l = Element.Location();
 
         let s = 0;
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             l.unit = units[unitIds[i]];
-            const set = AtomSet.unitGetByIndex(atoms, i);
+            const set = ElementSet.unitGetByIndex(elements, i);
 
 
-            for (let j = 0, _j = AtomGroup.size(set); j < _j; j++) {
-                l.atom = AtomGroup.getAt(set, j);
+            for (let j = 0, _j = ElementGroup.size(set); j < _j; j++) {
+                l.atom = ElementGroup.getAt(set, j);
                 s += p(l);
             }
         }
@@ -138,10 +138,10 @@ export namespace PropertyAccess {
         return s;
     }
 
-    function sumPropertySegmented(structure: Structure, p: Atom.Property<number>) {
-        const { atoms, units } = structure;
-        const unitIds = AtomSet.unitIds(atoms);
-        const l = Atom.Location();
+    function sumPropertySegmented(structure: Structure, p: Element.Property<number>) {
+        const { elements, units } = structure;
+        const unitIds = ElementSet.unitIds(elements);
+        const l = Element.Location();
 
         let s = 0;
 
@@ -149,22 +149,22 @@ export namespace PropertyAccess {
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unit = units[unitIds[i]];
             l.unit = unit;
-            const set = AtomSet.unitGetByIndex(atoms, i);
+            const set = ElementSet.unitGetByIndex(elements, i);
 
-            const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set.atoms);
+            const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set.elements);
             const residues = unit.hierarchy.residueSegments;
             while (chainsIt.hasNext) {
                 cC++;
 
                 const chainSegment = chainsIt.move();
-                const residuesIt = Segmentation.transientSegments(residues, set.atoms, chainSegment);
+                const residuesIt = Segmentation.transientSegments(residues, set.elements, chainSegment);
                 while (residuesIt.hasNext) {
                     rC++;
                     const residueSegment = residuesIt.move();
                     // l.atom = OrdSet.getAt(set, residueSegment.start);
                     // console.log(unit.hierarchy.residues.auth_comp_id.value(unit.residueIndex[l.atom]), l.atom, OrdSet.getAt(set, residueSegment.end))
                     for (let j = residueSegment.start, _j = residueSegment.end; j < _j; j++) {
-                        l.atom = AtomGroup.getAt(set, j);
+                        l.atom = ElementGroup.getAt(set, j);
                         vA++;
                         s += p(l);
                     }
@@ -177,20 +177,20 @@ export namespace PropertyAccess {
         return s;
     }
 
-    // function sumPropertyResidue(structure: Structure, p: Atom.Property<number>) {
+    // function sumPropertyResidue(structure: Structure, p: Element.Property<number>) {
     //     const { atoms, units } = structure;
-    //     const unitIds = AtomSet.unitIds(atoms);
-    //     const l = Atom.Location();
+    //     const unitIds = ElementSet.unitIds(atoms);
+    //     const l = Element.Location();
 
     //     let s = 0;
 
     //     for (let i = 0, _i = unitIds.length; i < _i; i++) {
     //         const unit = units[unitIds[i]];
     //         l.unit = unit;
-    //         const set = AtomSet.unitGetByIndex(atoms, i);
+    //         const set = ElementSet.unitGetByIndex(atoms, i);
     //         const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set.atoms);
     //         while (residuesIt.hasNext) {
-    //             l.atom = AtomGroup.getAt(set, residuesIt.move().start);
+    //             l.atom = ElementGroup.getAt(set, residuesIt.move().start);
     //             s += p(l);
     //         }
     //     }
@@ -198,16 +198,16 @@ export namespace PropertyAccess {
     //     return s;
     // }
 
-    function sumPropertyAtomSetIt(structure: Structure, p: Atom.Property<number>) {
-        const { atoms, units } = structure;
+    function sumPropertyAtomSetIt(structure: Structure, p: Element.Property<number>) {
+        const { elements, units } = structure;
 
         let s = 0;
-        const atomsIt = AtomSet.atoms(atoms);
-        const l = Atom.Location();
+        const atomsIt = ElementSet.elements(elements);
+        const l = Element.Location();
         while (atomsIt.hasNext) {
             const a = atomsIt.move();
-            l.unit = units[Atom.unit(a)];
-            l.atom = Atom.index(a);
+            l.unit = units[Element.unit(a)];
+            l.atom = Element.index(a);
             s += p(l);
         }
         return s;
@@ -215,7 +215,7 @@ export namespace PropertyAccess {
 
     // function sumPropertySegmentedMutable(structure: Structure, p: Property<number>) {
     //     const { atoms, units } = structure;
-    //     const unitIds = AtomSet.unitIds(atoms);
+    //     const unitIds = ElementSet.unitIds(atoms);
     //     const l = Property.createLocation();
 
     //     let s = 0;
@@ -223,7 +223,7 @@ export namespace PropertyAccess {
     //     for (let i = 0, _i = unitIds.length; i < _i; i++) {
     //         const unit = units[unitIds[i]];
     //         l.unit = unit;
-    //         const set = AtomSet.unitGetByIndex(atoms, i);
+    //         const set = ElementSet.unitGetByIndex(atoms, i);
 
     //         const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
     //         const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);
@@ -245,18 +245,18 @@ export namespace PropertyAccess {
 
     // function sumDirect(structure: Structure) {
     //     const { atoms, units } = structure;
-    //     const unitIds = AtomSet.unitIds(atoms);
+    //     const unitIds = ElementSet.unitIds(atoms);
 
     //     let s = 0;
 
     //     for (let i = 0, _i = unitIds.length; i < _i; i++) {
     //         const unitId = unitIds[i];
     //         const unit = units[unitId];
-    //         const set = AtomSet.unitGetByIndex(atoms, i);
+    //         const set = ElementSet.unitGetByIndex(atoms, i);
     //         //const { residueIndex, chainIndex } = unit;
     //         const p = unit.conformation.atomId.value;
-    //         for (let j = 0, _j = AtomGroup.size(set); j < _j; j++) {
-    //             const aI = AtomGroup.getAt(set, j);
+    //         for (let j = 0, _j = ElementGroup.size(set); j < _j; j++) {
+    //             const aI = ElementGroup.getAt(set, j);
     //             s += p(aI);
     //         }
     //     }
@@ -266,7 +266,7 @@ export namespace PropertyAccess {
 
     // function concatProperty(structure: Structure, p: Property<string>) {
     //     const { atoms, units } = structure;
-    //     const unitIds = AtomSet.unitIds(atoms);
+    //     const unitIds = ElementSet.unitIds(atoms);
     //     const l = Property.createLocation(structure);
 
     //     let s = [];
@@ -274,7 +274,7 @@ export namespace PropertyAccess {
     //     for (let i = 0, _i = unitIds.length; i < _i; i++) {
     //         const unitId = unitIds[i];
     //         l.unit = units[unitId];
-    //         const set = AtomSet.unitGetByIndex(atoms, i);
+    //         const set = ElementSet.unitGetByIndex(atoms, i);
     //         const { residueIndex, chainIndex } = l.unit;
 
     //         for (let j = 0, _j = OrdSet.size(set); j < _j; j++) {
@@ -343,7 +343,7 @@ export namespace PropertyAccess {
         //console.log('__x', sumProperty(structures[0], l => l.unit.conformation.x[l.atom]));
         console.timeEnd('__x')
 
-        //const authSeqId = Atom.property(l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom]));
+        //const authSeqId = Element.property(l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom]));
 
         //const auth_seq_id = Q.props.residue.auth_seq_id;
         const auth_comp_id = Q.props.residue.auth_comp_id;