diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts index 36891fbe3be088b587a3ff6c190fc5270c01334d..54eef86038f21229801286ba6dd8c5628b808758 100644 --- a/src/mol-model/structure/query/selection.ts +++ b/src/mol-model/structure/query/selection.ts @@ -16,8 +16,10 @@ type Selection = // TODO: Do not allow to change unit set in the middle of a query, create a differnt language to control assemblies etc. /* type Selection = - | { kind: 'sequence', units: UnitCollection, sets: AtomSet[] } - | { kind: 'atom-set', units: UnitCollection, set: AtomSet } + | { kind: 'sequence', structure: Structure, sets: AtomSet[] } + | { kind: 'atom-set', structure: Structure, set: AtomSet } + + structure allows for good unions. */ namespace Selection { diff --git a/src/mol-model/structure/structure.ts b/src/mol-model/structure/structure.ts index 0d5c8bad60f2489276a28cc76d0ee641635cd916..fbd00475512b275cd41c23c562f3ccf75adaa336 100644 --- a/src/mol-model/structure/structure.ts +++ b/src/mol-model/structure/structure.ts @@ -6,8 +6,9 @@ import Atom from './structure/atom' import AtomSet from './structure/atom/set' +import AtomGroup from './structure/atom/group' import Structure from './structure/structure' import Unit from './structure/unit' import Symmetry from './structure/symmetry' -export { Atom, AtomSet, Structure, Unit, Symmetry } \ No newline at end of file +export { Atom, AtomSet, AtomGroup, Structure, Unit, Symmetry } \ No newline at end of file diff --git a/src/mol-model/structure/structure/atom/group.ts b/src/mol-model/structure/structure/atom/group.ts new file mode 100644 index 0000000000000000000000000000000000000000..be6274ba2ba3407f26c44ec61cd6abdbae9dc110 --- /dev/null +++ b/src/mol-model/structure/structure/atom/group.ts @@ -0,0 +1,46 @@ +/** + * 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 { + set: OrderedSet, + id: number +} + +namespace AtomGroup { + export const Empty = createNew(OrderedSet.Empty) + + // export function singleton(idx: number) { + // return create(OrderedSet.ofSingleton(idx)); + // } + + export function createNew(set: OrderedSet) { + return { id: nextId(), set }; + } + + export function create(unit: Unit, set: OrderedSet): AtomGroup { + if (OrderedSet.areEqual(set, unit.naturalGroup.set)) return unit.naturalGroup; + return createNew(set); + } + + // export function size(group: AtomGroup) { return OrderedSet.size(group.set); } + // export function has(group: AtomGroup, atom: number) { return OrderedSet.has(group.set, atom); } + // export function getAt(group: AtomGroup, i: number) { return OrderedSet.getAt(group.set, i); } + // export function indexOf(group: AtomGroup, atom: number) { return OrderedSet.indexOf(group.set, atom); } + // export function hashCode(group: AtomGroup) { return OrderedSet.hashCode(group.set); } + // export function areEqual(a: AtomGroup, b: AtomGroup) { return OrderedSet.areEqual(a.set, b.set); } + + let _id = 0; + function nextId() { + const ret = _id; + _id = (_id + 1) % 0x3fffffff; + return ret; + } +} + +export default AtomGroup \ No newline at end of file diff --git a/src/mol-model/structure/structure/atom/unit.ts b/src/mol-model/structure/structure/atom/unit.ts deleted file mode 100644 index 10313f9120545a0dcb7d8b394aff2c9f048f7ece..0000000000000000000000000000000000000000 --- a/src/mol-model/structure/structure/atom/unit.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author David Sehnal <david.sehnal@gmail.com> - */ - -// TODO : wrap OrderedSet with and include "id" to identify unique (sub)sets in AtomSet and the ability to cache data (also include "ancestor" field for effictient subsets). - -import { OrderedSet } from 'mol-data/int' - -interface AtomUnit { - set: OrderedSet, - id: number, - ancestor?: AtomUnit -} - -namespace AtomUnit { - export function create(set: OrderedSet, ancestor?: AtomUnit): AtomUnit { - if (!ancestor) { - return { id: nextId(), set }; - } - if (OrderedSet.areEqual(set, ancestor.set)) return ancestor; - return { id: nextId(), set, ancestor: ancestor.ancestor || ancestor }; - } - - let _id = 0; - function nextId() { - const ret = _id; - _id = (_id + 1) % 0x3fffffff; - return ret; - } -} - -export default AtomUnit \ No newline at end of file diff --git a/src/mol-model/structure/structure/structure.ts b/src/mol-model/structure/structure/structure.ts index feca0801972d0c95b409c0a0742f72a99efa625f..9d25590e4cd1cf317f31cace6c0dc0e29905ee57 100644 --- a/src/mol-model/structure/structure/structure.ts +++ b/src/mol-model/structure/structure/structure.ts @@ -10,6 +10,7 @@ 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' @@ -35,7 +36,8 @@ namespace Structure { const builder = Builder(); for (let c = 0; c < chains.count; c++) { - const unit = Unit.create(c, model, SymmetryOperator.Default); + const group = AtomGroup.createNew(OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1])); + const unit = Unit.create(c, model, SymmetryOperator.Default, group); builder.add(unit, OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1])); } diff --git a/src/mol-model/structure/structure/symmetry.ts b/src/mol-model/structure/structure/symmetry.ts index abb2e10026ab263cdf5fe743eacb4186d9e73726..daa45f3fb6bf01fd034d057ac489af7d7962f4f0 100644 --- a/src/mol-model/structure/structure/symmetry.ts +++ b/src/mol-model/structure/structure/symmetry.ts @@ -36,7 +36,7 @@ function buildAssemblyImpl(structure: Structure, name: string) { for (const oper of g.operators) { for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) { const unit = units.get(unitIds[uI]); - assembler.add(Unit.create(unitId++, unit.model, oper), AtomSet.unitGetByIndex(atoms, uI)); + assembler.add(Unit.create(unitId++, unit.model, oper, unit.naturalGroup), AtomSet.unitGetByIndex(atoms, uI)); } } } diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts index b833b664c370fe51b19b6a59fddbdfb8c94f8408..e8edaa4c4f0e2a4964daa9c1bb6529a0a19e05dc 100644 --- a/src/mol-model/structure/structure/unit.ts +++ b/src/mol-model/structure/structure/unit.ts @@ -5,6 +5,7 @@ */ import SymmetryOperator from 'mol-math/geometry/symmetry-operator' +import AtomGroup from './atom/group' import { Model } from '../model' interface Unit extends SymmetryOperator.ArrayMapping { @@ -18,6 +19,9 @@ interface Unit extends SymmetryOperator.ArrayMapping { // The transform and and inverse are baked into the "getPosition" function readonly operator: SymmetryOperator, + // The "full" atom group corresponding to this unit. + readonly naturalGroup: AtomGroup, + // Reference some commonly accessed things for faster access. readonly residueIndex: ArrayLike<number>, readonly chainIndex: ArrayLike<number>, @@ -28,7 +32,7 @@ interface Unit extends SymmetryOperator.ArrayMapping { } namespace Unit { - export function create(id: number, model: Model, operator: SymmetryOperator): Unit { + export function create(id: number, model: Model, operator: SymmetryOperator, naturalGroup: AtomGroup): Unit { const h = model.hierarchy; const { invariantPosition, position, x, y, z } = SymmetryOperator.createMapping(operator, model.conformation); @@ -36,6 +40,7 @@ namespace Unit { id, model, operator, + naturalGroup, residueIndex: h.residueSegments.segmentMap, chainIndex: h.chainSegments.segmentMap, hierarchy: model.hierarchy,