From b4aab810ad5d999b0a6d177acdd114b1c8748450 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Fri, 10 Nov 2017 22:24:48 +0100 Subject: [PATCH] Working on structure data model --- src/mol-model/structure/query/selection.ts | 6 ++- src/mol-model/structure/structure.ts | 3 +- .../structure/structure/atom/group.ts | 46 +++++++++++++++++++ .../structure/structure/atom/unit.ts | 34 -------------- .../structure/structure/structure.ts | 4 +- src/mol-model/structure/structure/symmetry.ts | 2 +- src/mol-model/structure/structure/unit.ts | 7 ++- 7 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 src/mol-model/structure/structure/atom/group.ts delete mode 100644 src/mol-model/structure/structure/atom/unit.ts diff --git a/src/mol-model/structure/query/selection.ts b/src/mol-model/structure/query/selection.ts index 36891fbe3..54eef8603 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 0d5c8bad6..fbd004755 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 000000000..be6274ba2 --- /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 10313f912..000000000 --- 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 feca08019..9d25590e4 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 abb2e1002..daa45f3fb 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 b833b664c..e8edaa4c4 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, -- GitLab